怎么下载安装并创建一个例子,可以去网上找,有很多,如
http://www.cnblogs.com/yourihua/archive/2012/07/09/2583755.html
我这里是创建了一个叫test的例子,其文件结构如下
我们可以通过输入sh start-dev.sh快速启动
我是这样启动的,erl –smp进入erlangshell
observer:start() 打开监控器
debugger:start() 打开调试器,把所有代码都添加进去,便于调试
application:start(crypto).
application:start(test).
这样就启动mochiweb
mochiweb的流程如下
一开始启动test_app:start/2,确保已加载所依赖到代码,
然后启动test_sup督程,创建test_web拥程,
test_web:start/1 参数:
这时它定义了一个匿名函数Loop,并调用
其参数实际为[{name,test_web},{loop,test_web:loop(Reg,docroot)},{ip,"0.0.0.0"},{port,8000}]
小记proplists
19> Option1=[{a,1},{b,2},{c,3}].
[{a,1},{b,2},{c,3}]
20> proplists:lookup(a, Option1).
{a,1}
21> proplists:get_value(a, Option1).
1
22> proplists:delete(a, Option1).
[{b,2},{c,3}]
在这里,转换参数,然后调用
参数就改动了loop,变成
mochiweb_http:loop(S, test_web:loop(Reg,docroot))
把传递下来的参数转为记录mochiweb_socket_server存储
此时参数为:
这里有个问题不理解,
24> sets:new().
{set,0,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
{{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}}
为什么会这样呢?
然后就启用gen_server服务,并注册为test_web
在mochiweb_socket_server:init里调用mochiweb_socket_server:listen/3创建监听,
监听创建成功后,调用mochiweb_socket_server:new_acceptor_pool/2新建16个接收进程
而在mochiweb_acceptor:init里有这样一段代码:
它会从监听那里接收数据,如果接到这样的信息
就会调用mochiweb_ socket_server:handle_info,其主要是又创建这样一个进程来接收监听那数据。
如果收到
它会先test_web(也就是模块mochiweb_ socket_server)发起异步调用,
其主要是维护mochiweb_socket_server里的active_sockets的数量保持为pool_size(16)
就是说它会把自身从进程池删除,然后新建一个进程,添加到进程池去
然后就是mochiweb_ socket_server:Loop(Socket),实际上就是
mochiweb_http:loop(Socket, test_web:loop(Reg,docroot)),
到这里,就开始真正处理请求了,可以说都是准备工作
这回就复杂了,最讨厌这样的函数了,但没法,继续追踪
在mochiweb_http:loop/2中
在mochiweb_http
中,它会把请求转换成一定的格式
再执行以下代码
其中Req为:
这里又有个疑问:
在mochiweb:new_request({Socket,Request,lists:reverse(Headers)})里它调用
但在mochiweb_request里找不到new方法
接着看
还记得docroot是什么?
就是你放html文件的地方
在test_web里
就这么简单,但我不明白Reg作为一个数据结构,怎么能像模块那样调用呢?
紧接着是后续处理操作,
mochiweb_http
可以简单理解为程序退出
突然间又有个想法,mochiweb_request:new(Socket,
Method,
Uri,
Version,
mochiweb_headers:make(Headers));
会不会像java那样,是实例化一个模块呢?做了下测试
果真如此,那么上面那些疑问也就解决了,再来看下它是怎么加载文件的
调来调去不怎么好写,我弄了张断章取义的图,以助理解
至此基本流程算是结束,但里面还有很多细节未去仔细研究
gen_tcp理解:
gen_tcp:listen监听时用了一个端口A,
gen_tcp:accept 当有请求进来被A监听到,就创建端口B去处理这个请求,然后A继续监听
gen_tcp:recv 从端口B取数据
刚接触不就,若有所错误,还望指出,留言探讨,共同进步
对了,erlang版本过低是没有observer这个组件的,对源码编译安装出错的朋友,可以到这个网址去下载安装版
http://www.erlang-solutions.com/section/132/download-erlang-otp