这都是在headers函数中进行的,还是看mochiweb_http模块的代码:
-
headers(Socket, Request, Headers, HttpLoop, HeaderCount) ->
-
case gen_tcp:recv(Socket, 0, ?IDLE_TIMEOUT) of
-
{ok, http_eoh} ->
-
inet:setopts(Socket, [{packet, raw}]),
-
% 将Socket连接、HTTP请求信息(路径、请求方法、HTTP版本)以及请求消息头列表打包成参数化模块(mochiweb_request)的实例对象
-
Req = mochiweb:new_request({Socket, Request,
-
lists:reverse(Headers)}),
-
HttpLoop(Req), % 让用户编写的函数处理HTTP请求
-
case Req:should_close() of
-
true ->
-
gen_tcp:close(Socket),
-
exit(normal);
-
false ->
-
Req:cleanup(),
-
mochiweb_http:loop(Socket, HttpLoop)
-
end;
-
{ok, {http_header, _, Name, _, Value}} ->
-
headers(Socket, Request, [{Name, Value} | Headers],HttpLoop,
-
1 + HeaderCount);
-
_Other ->
-
gen_tcp:close(Socket),
-
exit(normal)
-
end.
以上处理逻辑都被重新包装到新函数Loop(又一个函数对象),这一包装过程是在mochiweb_http:parse_options函数中进行的。新的Loop函数对象将作为OTP gen_server模块mochiweb_socket_server的运行状态(State)的一部分(这个OTP server模块被mochiweb_http启动,Loop函数对象作为启动参数之一传给mochiweb_socket_server,进入模块的State)
三、接受HTTP请求
作为Mochiweb HTTP Web服务器的核心,mochiweb_socket_server模块负责处理浏览器的HTTP连接(本质上还是socket连接)。
该OTP模块在初始时(init(…)函数)打开trap_exit使服务器进程成为系统进程,并开始在端口监听网络连接,同时,启动(spawn_link)一个HTTP请求接收进程,这个进程执行的是acceptor_loop(…)函数。acceptor_loop接收一个三元tuple作为参数,tuple参数的第一个元素是mochiweb_socket_server服务器进程Pid,第二个是在网络端口进行监听的监听器,第三个就是前面提到的包装好的Loop函数对象,如下:
-
acceptor_loop({Server, Listen, Loop}) ->
-
case catch gen_tcp:accept(Listen) of
-
{ok, Socket} ->
-
gen_server:cast(Server, {accepted, self()}),
-
call_loop(Loop, Socket);
-
{error, closed} ->
-
exit({error, closed});
-
Other ->
-
error_logger:error_report(
-
[{application, mochiweb},
-
"Accept failed error",
-
lists:flatten(io_lib:format("~p", [Other]))]),
-
exit({error, accept_failed})
-
end.
当HTTP请求接收进程收到一个浏览器HTTP连接请求后,先以“发送后不管”的方式(即cast)发accepted消息通知mochiweb_socket_server服务器:有HTTP请求来啦,本进程已接受并负责处理。随后该进程就会调用用户定制的函数对象处理请求。进程是在call_loop函数中执行上述的Loop函数对象
call_loop(Loop, Socket) ->
Loop(Socket).
这个在服务器初始阶段启动的HTTP请求接收进程的Pid被作为mochiweb_socket_server状态的一部分保持在State记录的acceptor字段。mochiweb_socket_server服务器进程的状态还记录了Mochiweb服务器当前能处理的最大连接数(max),每当收到HTTP请求接收进程发过来的一个accepted消息,就减少一个最大连接数,同时,除非当前最大连接数为零,再生成一个新的HTTP请求接收进程,并将mochiweb_socket_server服务器进程的运行状态(State)的acceptor字段替换成这个新的HTTP请求接收进程Pid。这就是Mochiweb接受HTTP请求的策略,有点像自动步枪,尽管枪膛里只有一发子弹,但每射出一发子弹,火药爆炸带来的一部分气体压力自动的将新的子弹压入枪膛,于是就可以连续不断的射击了。
总结
服务器端的业务逻辑在一个函数中实现,然后这个函数像数据对象那样嵌入到Mochiweb中,这是典型的函数式程序设计。这个函数通过mochiweb_request实例对象获取请求的相关信息,并将响应通过该对象发送给客户端浏览器。
每个HTTP请求由一个Erlang进程负责处理,充分发挥了Erlang多线程的优势。一个连接对应一个Erlang进程,比较适合comet这样的应用,并发请求的处理能力与Erlang线程数量正相关。相关测试见A Million-user Comet Application with Mochiweb 。
Mochiweb的实现大量使用了参数化模块的特性,包括核心的代表HTTP请求的mochiweb_request实例对象,某种程度上使Mochiweb有了基于对象(Object-based)的特点。不过参数化模块还是“undocumented and unsupported”,可能在未来版本的Erlang中有一定不兼容风险,但是如果Mochiweb用的人足够多,应用足够广,我想将来的Erlang说不定反受Mochiweb应用的影响,官方确定参数化模块这一特性呢。
mochiweb这类的轻量级Web服务器小巧灵活,它的Web应用不能像JSP、ASP那样方便的写服务器端代码,也没有很多重型Web服务器常见的功能,但胜在易于理解,又足够快。比较适合纯动态内容生成的Web应用,如comet。可以作为现有Web服务器的补充。Facebook就用它做了Web在线聊天。
分享到:
相关推荐
这个实例将帮助我们理解Mochiweb是如何工作的,并如何使用它来构建一个简单的Web服务器。Erlang是一种并发性极强、容错性高的语言,特别适合构建分布式系统,而Mochiweb则是Erlang生态系统中的一个重要组件。 首先...
这个 "erlang mochiweb-test demo" 压缩包很可能是为了展示如何使用 Mochiweb 在 Erlang 中构建一个简单的 Web 应用程序或测试环境。 Mochiweb 的核心组件包括以下几个部分: 1. **HTTP 服务器**:Mochiweb 提供了...
通过学习和分析这个项目,开发者可以深入理解Erlang的并发模型、Mochiweb的工作原理,以及如何利用它们构建高效、可靠的Web服务。同时,这也为扩展到更复杂的实时应用,如协作工具、游戏服务器等,提供了基础。
MochiWeb 的最新版本可在MochiWeb 的邮件列表位于 设置 MochiWeb 环境需要 Erlang OTP,可在使用项目创建一个新的 mochiweb:make app PROJECT=project_name 要使用特定目录中的项目创建新的 mochiweb: make app ...
MochiWeb的邮件列表位于 R12B兼容性:MochiWeb的母版已通过R14A及更高版本进行了测试。 与R12B兼容的分支在单独维护。为方便起见,该存储库的R12B分支有时会在官方存储库中进行镜像。 要使用项目创建新的mochiweb,...
- **轻量级**:Mochiweb和Cowboy都设计为轻量级,启动快速,资源占用少,适合部署在资源有限的环境中。 总的来说,Erlang Web框架如Mochiweb和Cowboy,为开发者提供了一种高效且可靠的构建Web服务的方式,尤其适用...
张琨分享的内容涉及了“三人行网络教育平台”的Web架构设计和实现,本文将围绕这一主题,深入讲解服务器拓扑结构、缓存系统设计、存储设计架构以及具体服务与应用的设计。 首先,总体架构的设计应考虑满足当前业务...
RPSSL彗星 RPSSL-Rock-Paper-Scissors-Spock-Lizard是一款简单但着名的2人游戏。 通常,它是第一人称自己玩的,但这是网络版本。 ... ... 因为它使用的资源很少,所以我们可以使其永远处于阻塞状态,并保持连接处于打开...
通过以上分析,我们可以看到该项目不仅是一次实际操作的体验,也是对Erlang语言特性及其在Web开发领域应用的一次深入探索。对于有兴趣学习Erlang或者希望深入了解其在网络编程中的应用的开发者来说,这是一个非常有...
在国外,Erlang被广泛应用于Ejabberd即时通讯服务器、RabbitMQ消息队列、CouchDB文档数据库、Mochiweb轻量级Web服务器以及Disco分布式计算框架。 Erlang与传统的操作系统如Unix相比,具有独特的设计哲学。在Unix中...
- WebIM服务器使用Erlang的“mochiweb”实现,可以支持大量的并发长连接,从而确保系统的高可用性和扩展性。 - **消息接口设计**: - AJAX POST消息:用户通过POST方式向SNS主服务器发送消息。 - 主服务器处理并...
2. **多框架兼容**:支持各种框架,例如Spring、Grails、Express、Rails、Lift、MochiWeb等。 3. **多服务集成**:能够与多种数据服务和其他服务集成,如MySQL、PostgreSQL、MongoDB、Redis、RabbitMQ等。 4. **多云...
Webmachine 是一个应用层,为 mochiweb 提供 HTTP 语义的特性,定义一个简单而清晰的连接应用的方式。 标签:Webmachine Web框架
它目前支持Cowboy,Inet,Mochiweb,Webmachine和Yaws。 SimpleBridge用作两个最受欢迎的Erlang Web框架到Web服务器的桥梁: 和 从某种意义上讲,它类似于 ,除了具有一些关键的改进/不同之处: 轻松扩展-需要...
【标题】:深入理解Erlang在Web开发中的应用...通过以上分析,我们可以看到,"web1"项目利用Erlang的强大功能,构建了一个高效、可靠的Web服务。对于想要深入理解和应用Erlang的开发者来说,这是一个值得研究的实例。
专为高质量和工业用例而设计。 -Tsung是适用于各种协议(包括HTTP,XMPP,LDAP等)的高性能基准框架。 -Lisp风味Erlang(LFE) -Erlang Web MVC,现在具有Comet功能 -MochiWeb是用于构建轻量级HTTP服务器的Erlang库...
2. **Erlang实现Websocket**:在Erlang中,可以使用如`cowboy`或`mochiweb`这样的Web框架来处理Websocket连接。它们提供了方便的中间件,使得在Erlang进程中直接处理Websocket连接成为可能。例如,`cowboy`中的`...
该框架基于Mochiweb(一款用Erlang编写的Web服务器)构建,旨在帮助开发者轻松构建遵循HTTP语义的服务,同时避免了在业务逻辑中直接处理HTTP相关的复杂性。 ##### 原则 - **默认行为**:Webmachine实现了一些默认...
- Profile:性能分析工具 - 工具集:提供各种开发辅助工具 **Erlang 的高性能和高可靠性** Erlang 以其简洁的代码实现高并发,如单个CPU可以处理16000个并发请求,优于某些顶级的Web服务器。其代码覆盖率工具cover...