- 浏览: 581536 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
JamAndVariousAbalone:
存储方式的不同吧。gb_tree是平衡树,list是线性结构。 ...
gb_trees和lists的访问效率相差很大 -
genesislive:
eporf:analyse()写错了,应该改成eprof:an ...
Erlang程序的性能测试工具(1) -
vampirezh:
高手啊 求带 ! 请列出带徒标准
Erlang的未来(2008) -
aiquantong:
great!
rebar工具使用备忘录 (1) -
wccxiaoan:
basho的资源 都没办法打开,不过还是有帮助,谢谢。
关于webmachine
Web服务器的基本工作大致分3步:
1. 接收HTTP请求;
2. 处理HTTP请求,生成响应内容;
3. 发送响应
一、处理请求和发送响应
模块mochiweb_request可说是Mochiweb处理HTTP请求的核心部分,它总共负责了第2步和第3步工作。因此参数化模块mochiweb_request的实例不像它的模块名那样单纯:它还负责将请求的响应(通过Socket连接,调用gen_tcp:send)发还(response)给浏览器。这个模块是一个参数化模块。这意味着它具有基于对象(Object-based)的特点,它的每个实例化对象代表一个用户请求,用户可以像OO那样操作HTTP请求:获取请求信息,生成响应内容等。
对静态内容(如html文件,静态图片)来说,无非是读取文件系统中静态文件的内容作为响应消息体(Body)发送给客户端浏览器。
对动态内容来说,生成响应内容的业务逻辑是用户通过编程实现的:解析请求(包括URL路径和HTTP请求头),然后生成相应的响应内容。用户编写业务逻辑处理函数,然后将函数插入到mochiweb中。此函数带有一参数,该参数是参数化模块mochiweb_request的实例(假设为Req),在这个定制函数中可以通过这个Req实例对象获取浏览器请求的所有信息(包括URL路径和HTTP请求头),处理后的响应数据也通过Req实例提供的函数发还给浏览器,有好几种方式:
1. 通过Req实例对象直接发还给浏览器:
a). 通过这个Req实例对象的response/1函数直接发还给浏览器:
这个函数接收一个tuple参数,参数的第一个元素是HTTP状态码(比如200),第二个元素是响应消息头列表(一个二元tuple,key和value都是字符串,如{"Content-Type", "image/jpeg"}),第三个元素即为HTTP响应内容;如果是动态内容,采用response函数直接发还响应数据还是比较方便的。
b). 如果是静态文件,通过Req的serve_file(...)函数可以直接将文件发还给浏览器,告诉此函数文件的Web根目录(doc_root)和相对路径就可以将指定的静态文件发给浏览器了。doc_root目录一般在配置文件中设置,这个目录下的所有文件都可以通过HTTP访问。
c). 一些常见的例行响应:
不存在的URL请求返回404错误,可以直接调用Req:not_found()
一切正常,调用Req:ok({..., Body})直接返回状态码为200的HTTP响应
b,c两种情况的内部其实还是调用的Req:response()
2. 通过Response模块对象将响应发还给浏览器:
Req:response函数会返回一个mochiweb_response参数化模块实例对象(假设为Response),Response实例对象包含有对应的Req实例对象。通过Response对象可以得到响应的相关信息(如响应状态码,响应消息头,对应的Req对象),它还有一个send函数可以将响应数据发还给浏览器(它的实现其实还是调用Req对象的send函数进行的)。Response之所以还要有send函数是为了发送chunked数据(HTTP 1.1)的方便,在第一次响应完成后,后继的chunk数据就可以通过最初返回的Response对象继续进行发送了,为此Response有个函数write_chunk()专门干这事,write_chunk检查了请求消息头中的HTTP 版本消息后就调用Response:send。
因此,响应内容最终都是由参数化模块mochiweb_request的response/1函数发送的。而这个response(...)函数内部最后调用了Req:send(Data)函数将响应通过socket连接(调用gen_tcp:send)返还给浏览器,这一发送过程又分成两个阶段:响应消息头(Headers)的发送和消息体(Body)的发送,这两步都是通过Req:send完成的。
总结:对于使用Mochiweb的程序员来说,他编写的服务器端处理HTTP请求的函数必须带有一个参数,这个参数代表了mochiweb_request参数化模块的一个实例对象。通过这个实例程序员可以得到HTTP请求的所有信息(包括路径、请求参数以及HTTP请求消息头),然后生成响应,他还可以通过该mochiweb_request实例对象将响应数据发还给浏览器。
1. 如果响应的是静态文件,可以通过Request:server_file()函数发送响应;
2. 如果响应是动态生成的内容,通过Request:response()函数发送响应数据(文本数据和二进制数据都可以);
3. 如果是chunk响应,第一次调用Request:response()函数发送数据后,该函数会返回一个Response实例对象(参数化模块mochiweb_response的一个实例),以后的响应数据可以通过这个Response实例对象(调用Response:write_chunk(Data))发送后续的响应数据。
二、Web服务器的业务处理逻辑如何嵌入到Mochiweb
业务处理逻辑被程序员编写成一个函数(函数式编程中函数也是一种数据,以下称为HttpLoop),处理函数HttpLoop是作为mochiweb启动时的参数之一进入Mochiweb,Mochiweb是这样启动的:
Request实例对象最终要调用gen_tcp:send(Socket,...)将响应数据由socket连接发给浏览器,因此,Request实例对象应该持有HTTP请求的socket连接。这个目标是这样实现的:
在启动过程中,mochiweb_http又对用户的HttpLoop函数进行了重新包装
每个浏览器连接请求对应着一个Socket连接,新的Loop函数以此Socket作为参数,然后通过mochiweb_http:loop函数对Socket连接和用户自定义的HttpLoop函数进行了处理,简单的说,这个函数做了如下工作:
1. 将Socket连接设置成能处理HTTP数据包;
inet:setopts(Socket, [{packet, http}])
2. 准备接收socket连接传来的数据(gen_tcp:recv(Socket,...));
3. 当收到数据时,
a). 将HTTP消息头数据提出(成为{HeaderName, HeaderValue}的tuple列表)
b). 生成一个参数化模块mochiweb_request的实例对象,并将Socket连接、HTTP请求信息(路径、请求方法、HTTP版本)以及请求消息头列表包装到此实例对象中,然后调用用户的HttpLoop对请求进行处理和响应(如前所述,处理得到的响应数据也在用户编写的HttpLoop函数中被发送给浏览器),最后根据HTTP请求信息决定是简单的关闭Socket连接,还是清理一下Req对象并保持连接(例如对keep-alive,chunk等类型的HTTP请求,以及还没完成数据传送的HTTP请求),以便继续让HttpLoop函数进行处理,这都是在headers函数中进行的,还是看mochiweb_http模块的代码:
以上处理逻辑都被重新包装到新函数Loop(又一个函数对象),这一包装过程是在mochiweb_http:parse_options函数中进行的。新的Loop函数对象将作为OTP gen_server模块mochiweb_socket_server的运行状态(State)的一部分(这个OTP server模块被mochiweb_http启动,Loop函数对象作为启动参数之一传给mochiweb_socket_server,进入模块的State)
3. 接受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函数对象,如下:
当HTTP请求接收进程收到一个浏览器HTTP连接请求后,先以“发送后不管”的方式(即cast)发accepted消息通知mochiweb_socket_server服务器:有HTTP请求来啦,本进程已接受并负责处理。随后该进程就会调用用户定制的函数对象处理请求。进程是在call_loop函数中执行上述的Loop函数对象
这个在服务器初始阶段启动的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在线聊天。
http://erlang-china.org/start/mochiweb_intro.html
http://erlang-china.org/misc/facebook_comet_in_mochiweb.html
http://erlang-china.org/misc/comet-and-erlang-a-perfect-match.html
嗯,多谢指漏:)
1. 接收HTTP请求;
2. 处理HTTP请求,生成响应内容;
3. 发送响应
一、处理请求和发送响应
模块mochiweb_request可说是Mochiweb处理HTTP请求的核心部分,它总共负责了第2步和第3步工作。因此参数化模块mochiweb_request的实例不像它的模块名那样单纯:它还负责将请求的响应(通过Socket连接,调用gen_tcp:send)发还(response)给浏览器。这个模块是一个参数化模块。这意味着它具有基于对象(Object-based)的特点,它的每个实例化对象代表一个用户请求,用户可以像OO那样操作HTTP请求:获取请求信息,生成响应内容等。
对静态内容(如html文件,静态图片)来说,无非是读取文件系统中静态文件的内容作为响应消息体(Body)发送给客户端浏览器。
对动态内容来说,生成响应内容的业务逻辑是用户通过编程实现的:解析请求(包括URL路径和HTTP请求头),然后生成相应的响应内容。用户编写业务逻辑处理函数,然后将函数插入到mochiweb中。此函数带有一参数,该参数是参数化模块mochiweb_request的实例(假设为Req),在这个定制函数中可以通过这个Req实例对象获取浏览器请求的所有信息(包括URL路径和HTTP请求头),处理后的响应数据也通过Req实例提供的函数发还给浏览器,有好几种方式:
1. 通过Req实例对象直接发还给浏览器:
a). 通过这个Req实例对象的response/1函数直接发还给浏览器:
Req:response({Code, ResponseHeaders, Body})
这个函数接收一个tuple参数,参数的第一个元素是HTTP状态码(比如200),第二个元素是响应消息头列表(一个二元tuple,key和value都是字符串,如{"Content-Type", "image/jpeg"}),第三个元素即为HTTP响应内容;如果是动态内容,采用response函数直接发还响应数据还是比较方便的。
b). 如果是静态文件,通过Req的serve_file(...)函数可以直接将文件发还给浏览器,告诉此函数文件的Web根目录(doc_root)和相对路径就可以将指定的静态文件发给浏览器了。doc_root目录一般在配置文件中设置,这个目录下的所有文件都可以通过HTTP访问。
c). 一些常见的例行响应:
不存在的URL请求返回404错误,可以直接调用Req:not_found()
一切正常,调用Req:ok({..., Body})直接返回状态码为200的HTTP响应
b,c两种情况的内部其实还是调用的Req:response()
2. 通过Response模块对象将响应发还给浏览器:
Req:response函数会返回一个mochiweb_response参数化模块实例对象(假设为Response),Response实例对象包含有对应的Req实例对象。通过Response对象可以得到响应的相关信息(如响应状态码,响应消息头,对应的Req对象),它还有一个send函数可以将响应数据发还给浏览器(它的实现其实还是调用Req对象的send函数进行的)。Response之所以还要有send函数是为了发送chunked数据(HTTP 1.1)的方便,在第一次响应完成后,后继的chunk数据就可以通过最初返回的Response对象继续进行发送了,为此Response有个函数write_chunk()专门干这事,write_chunk检查了请求消息头中的HTTP 版本消息后就调用Response:send。
因此,响应内容最终都是由参数化模块mochiweb_request的response/1函数发送的。而这个response(...)函数内部最后调用了Req:send(Data)函数将响应通过socket连接(调用gen_tcp:send)返还给浏览器,这一发送过程又分成两个阶段:响应消息头(Headers)的发送和消息体(Body)的发送,这两步都是通过Req:send完成的。
总结:对于使用Mochiweb的程序员来说,他编写的服务器端处理HTTP请求的函数必须带有一个参数,这个参数代表了mochiweb_request参数化模块的一个实例对象。通过这个实例程序员可以得到HTTP请求的所有信息(包括路径、请求参数以及HTTP请求消息头),然后生成响应,他还可以通过该mochiweb_request实例对象将响应数据发还给浏览器。
1. 如果响应的是静态文件,可以通过Request:server_file()函数发送响应;
2. 如果响应是动态生成的内容,通过Request:response()函数发送响应数据(文本数据和二进制数据都可以);
3. 如果是chunk响应,第一次调用Request:response()函数发送数据后,该函数会返回一个Response实例对象(参数化模块mochiweb_response的一个实例),以后的响应数据可以通过这个Response实例对象(调用Response:write_chunk(Data))发送后续的响应数据。
二、Web服务器的业务处理逻辑如何嵌入到Mochiweb
业务处理逻辑被程序员编写成一个函数(函数式编程中函数也是一种数据,以下称为HttpLoop),处理函数HttpLoop是作为mochiweb启动时的参数之一进入Mochiweb,Mochiweb是这样启动的:
mochiweb_http:start([{loop, HttpLoop},...])
Request实例对象最终要调用gen_tcp:send(Socket,...)将响应数据由socket连接发给浏览器,因此,Request实例对象应该持有HTTP请求的socket连接。这个目标是这样实现的:
在启动过程中,mochiweb_http又对用户的HttpLoop函数进行了重新包装
Loop = fun (Socket) -> mochiweb_http:loop(Socket, HttpLoop) end,
每个浏览器连接请求对应着一个Socket连接,新的Loop函数以此Socket作为参数,然后通过mochiweb_http:loop函数对Socket连接和用户自定义的HttpLoop函数进行了处理,简单的说,这个函数做了如下工作:
1. 将Socket连接设置成能处理HTTP数据包;
inet:setopts(Socket, [{packet, http}])
2. 准备接收socket连接传来的数据(gen_tcp:recv(Socket,...));
3. 当收到数据时,
a). 将HTTP消息头数据提出(成为{HeaderName, HeaderValue}的tuple列表)
b). 生成一个参数化模块mochiweb_request的实例对象,并将Socket连接、HTTP请求信息(路径、请求方法、HTTP版本)以及请求消息头列表包装到此实例对象中,然后调用用户的HttpLoop对请求进行处理和响应(如前所述,处理得到的响应数据也在用户编写的HttpLoop函数中被发送给浏览器),最后根据HTTP请求信息决定是简单的关闭Socket连接,还是清理一下Req对象并保持连接(例如对keep-alive,chunk等类型的HTTP请求,以及还没完成数据传送的HTTP请求),以便继续让HttpLoop函数进行处理,这都是在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)
3. 接受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在线聊天。
评论
8 楼
mryufeng
2010-01-14
mochiweb从设计和编码手法都非常成熟,确实很适合观摩学习...
7 楼
rain2005
2010-01-12
呵呵,这遍文章我是学习mochiweb的一个很好的起点,litaocheng大侠建议适合我这种刚刚掌握点erlang语法的同学学习哦。
6 楼
crackcell
2009-10-11
兄台写得挺简洁明了的,对我这种初看mochi源代码的人很有指导作用,多谢!
5 楼
litaocheng
2009-03-19
简单完美的michiweb
4 楼
cryolite
2009-03-18
kaiyangcheng 写道
写的非常棒,不过我(俺刚刚学erlang以前也没有太多接触web sever的编写)还希望楼主对mochiweb有一些更细致的介绍,比如举一些小例子具体说说如何利用它做一些web server;比如get(method)函数中取的方法有哪些,怎么用;一个小例子足以,不过希望能尽量详细。
http://erlang-china.org/start/mochiweb_intro.html
http://erlang-china.org/misc/facebook_comet_in_mochiweb.html
http://erlang-china.org/misc/comet-and-erlang-a-perfect-match.html
3 楼
kaiyangcheng
2009-03-18
写的非常棒,不过我(俺刚刚学erlang以前也没有太多接触web sever的编写)还希望楼主对mochiweb有一些更细致的介绍,比如举一些小例子具体说说如何利用它做一些web server;比如get(method)函数中取的方法有哪些,怎么用;一个小例子足以,不过希望能尽量详细。
2 楼
cryolite
2009-03-13
mryufeng 写道
mochi 是很轻量
嗯,多谢指漏:)
1 楼
mryufeng
2009-03-13
mochi 是很轻量
发表评论
-
NIF与OS线程
2013-08-31 01:29 1114NIF的OS线程编程模型可以参考The Art of Mult ... -
关于nif
2013-08-19 10:28 5154一、NIF的误用问题 使用NIF是很危险的,一不小心它就会搞 ... -
遇到的riak性能问题
2013-07-23 10:59 24281。 遇到一个奇怪的性能问题,多个进程中用riakc_pb_ ... -
folsom_metrics使用备忘
2013-06-07 15:41 1483folsom是一个通用的统计度量工具。使用很简单,关键是搞清它 ... -
Riak Core与folsom
2012-09-01 11:54 1506folsom是Riak从1.2开始引入。 -
关于Erlang/OTP的application参数配置
2012-08-26 23:27 9148Erlang/OTP中将完成特定功能的一组模块组织起来,称之 ... -
rebar工具使用备忘录 (5)
2012-08-23 18:17 1505haogongju、人人IT网、59n南龙、360doc、as ... -
lager的使用
2012-08-23 15:06 10563haogongju、人人IT网、59n南龙、360doc不要抄 ... -
rebar工具使用备忘录 (4)
2012-08-22 19:20 5620haogongju、人人IT网、59n南龙、360doc、as ... -
rebar工具使用备忘录 (3)
2012-08-22 19:18 1317haogongju、人人IT网、59n南龙、360doc不要抄 ... -
对Riak Core的探索 (9) cheatsheet
2012-08-12 12:58 1685haogongju、人人IT网、59n南龙、360doc不要抄 ... -
对Riak Core的探索 (8)
2012-08-11 18:52 1260haogongju、人人IT网、59n南龙、360doc不要抄 ... -
关于webmachine
2012-08-03 14:38 2828haogongju、人人IT网、59n ... -
使用dialyzer遇到的问题
2012-06-19 18:18 12051. 对自定义behaviour的警告 有洁癖的可能无法忍受这 ... -
关于erlang的iolist
2012-06-17 15:10 2836erlang字符串可以用list结构存放ASCII编码(0~2 ... -
关于erlang的binary
2012-06-02 16:03 73411. binary数据是可以在不 ... -
关于erlang的进程池
2012-05-30 18:42 6136有两种情况需要考虑使 ... -
riak对大数据文件或对象的支持问题
2012-05-24 19:24 1575很遗憾在2011年12月的时 ... -
riak资料汇编
2012-04-10 17:38 2552一、上手 各个操作系统平台上的安装说明:Installati ... -
对riak_core的探索 (5)
2012-04-05 17:31 0Coordinator的使用 一份partition有多个副 ...
相关推荐
Mochiweb的轻量级设计使得它在内存占用和性能上都有很好的表现。 **聊天室实现** 在这个基于Mochiweb的聊天室项目中,开发者可能使用了以下技术: 1. **HTTP服务器**:Mochiweb作为基础,负责处理用户的HTTP请求...
- **轻量级**:Mochiweb和Cowboy都设计为轻量级,启动快速,资源占用少,适合部署在资源有限的环境中。 总的来说,Erlang Web框架如Mochiweb和Cowboy,为开发者提供了一种高效且可靠的构建Web服务的方式,尤其适用...
NoticeSystem则利用了mochiweb的高效通信特性,采用了Erlang编程语言。MQserver使用了RabbitMQ作为基础的异步消息队列服务,而FileStoreServer结合了Varnish和MongoDB来实现静态资源的存储。 具体服务与应用的设计...
2. **多框架兼容**:支持各种框架,例如Spring、Grails、Express、Rails、Lift、MochiWeb等。 3. **多服务集成**:能够与多种数据服务和其他服务集成,如MySQL、PostgreSQL、MongoDB、Redis、RabbitMQ等。 4. **多云...
在国外,Erlang被广泛应用于Ejabberd即时通讯服务器、RabbitMQ消息队列、CouchDB文档数据库、Mochiweb轻量级Web服务器以及Disco分布式计算框架。 Erlang与传统的操作系统如Unix相比,具有独特的设计哲学。在Unix中...
- WebIM服务器使用Erlang的“mochiweb”实现,可以支持大量的并发长连接,从而确保系统的高可用性和扩展性。 - **消息接口设计**: - AJAX POST消息:用户通过POST方式向SNS主服务器发送消息。 - 主服务器处理并...
专为高质量和工业用例而设计。 -Tsung是适用于各种协议(包括HTTP,XMPP,LDAP等)的高性能基准框架。 -Lisp风味Erlang(LFE) -Erlang Web MVC,现在具有Comet功能 -MochiWeb是用于构建轻量级HTTP服务器的Erlang库...
- Erlang有许多Web开发框架,如Yaws、Mochiweb和Cowboy等。"web1"项目可能采用了其中一种,这些框架提供了HTTP服务器、路由处理和模板渲染等功能,帮助快速构建Web应用。 6. **数据持久化与数据库集成**: - ...
该框架基于Mochiweb(一款用Erlang编写的Web服务器)构建,旨在帮助开发者轻松构建遵循HTTP语义的服务,同时避免了在业务逻辑中直接处理HTTP相关的复杂性。 ##### 原则 - **默认行为**:Webmachine实现了一些默认...
elli相比其他Erlang Web服务器(如Yaws、Mochiweb、Cowboy)更专注于HTTP API服务,其设计更简洁,对于API开发更为友好。然而,不同的服务器在性能、功能和灵活性方面各有特点,选择哪一款取决于具体项目需求。 总...
在Erlang中,传统的面向对象设计模式并不适用,OTP提供了一套针对Erlang语言特性的设计模式。常见的OTP行为包括: - **gen_server**:用于维护状态或提供功能接口,适用于大多数业务逻辑。 - **gen_fsm**:用于处理...
还有Mochiweb2库,它提供了处理JSON数据类型的便捷方法。 为了在多核CPU上高效运行,Erlang程序使用大量的进程进行并发处理,避免共享内存结构以减少副作用。在实现时应尽量避免顺序瓶颈,可以使用pmap代替map来...