鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > erlang > >

mochiweb 源码阅读(六)

来源:互联网 作者:佚名 时间:2012-11-15 13:35
大家好,最近比较忙,游戏忙着上各个主流的大平台,事情比较多。还记得上次给大家推荐的Erlang的书吗?《Erlang/OTP并发编程实战》这本书在china-pub上已经有卖了,想学Erlang的朋友,可以买一本看看,地址:。一不小心又做广告了,呵呵,好书嘛,总是忍不住

  大家好,最近比较忙,游戏忙着上各个主流的大平台,事情比较多。还记得上次给大家推荐的Erlang的书吗?《Erlang/OTP并发编程实战》这本书在china-pub上已经有卖了,想学Erlang的朋友,可以买一本看看,地址:。一不小心又做广告了,呵呵,好书嘛,总是忍不住推荐给大家。

  回到今天的正题,继续和大家分析mochiweb源码,在上一篇,我们总结了下mochiweb_example_deps 这个模块的作用,以及简单介绍了下mochiweb_example的启动。这一篇,我们详细看下启动过程。

  首先,我们看下:mochiweb_example_web:start/1,代码如下:

start(Options) -> {DocRoot, Options1} = get_option(docroot, Options), Loop = fun (Req) -> ?MODULE:loop(Req, DocRoot) end, mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options1]).

  这里的参数是在 mochiweb_example_sup:web_specs/2 启动 mochiweb_example_web工作进程时传递过来的,也就是WebConfig,详细代码如下:

web_specs(Mod, Port) -> P = mochiweb_example_deps:local_path(["priv", "www"]), io:format("P = ~p~n", [P]), WebConfig = [{ip, {0,0,0,0}}, {port, Port}, {docroot, P}], {Mod, {Mod, start, [WebConfig]}, permanent, 5000, worker, dynamic}.

  好了,知道了这个参数的值,我们继续回到 mochiweb_example_web:start/1 函数:

  {DocRoot, Options1} = get_option(docroot, Options),这一行调用mochiweb_example_web:get_option/2,代码如下:

get_option(Option, Options) -> {proplists:get_value(Option, Options), proplists:delete(Option, Options)}.

  这里有2个系统函数,我们先看下:

  函数:proplists:get_value/2,erlang doc地址:,如下图:  

  这个函数,相当于 get_value(Key, List, undefined),所以我们重点看下:proplists:get_value/3,从列表中返回值的一个简单的键/值属性。如果从List查找到Key,将返回{Key,Value},该函数返回相应的值,否则返回默认值。

  函数:proplists:delete/2,从List中删除所有和Key相关的项。 erlang doc地址:,如下图:

  我们在shell上做些简单的测试,测试结果如下:

  

  好了,弄清楚了mochiweb_example_web:get_option/2函数,我们继续回到mochiweb_example_web:start/1 函数,看如下代码:

Loop = fun (Req) -> ?MODULE:loop(Req, DocRoot) end,

  这段代码也比较简单,定义个匿名函数,传递Req参数,匿名函数中就一行代码,调用本模块中的loop/2函数。这个函数我们先跳过,等真正运行该函数时,我们再回过头来看这个函数,这个函数代码如下:  

loop(Req, DocRoot) -> "/" ++ Path = Req:get(path), try case Req:get(method) of Method when Method =:= 'GET'; Method =:= 'HEAD' -> case Path of _ -> Req:serve_file(Path, DocRoot) end; 'POST' -> case Path of _ -> Req:not_found() end; _ -> Req:respond({501, [], []}) end catch Type:What -> Report = ["web request failed", {path, Path}, {type, Type}, {what, What}, {trace, erlang:get_stacktrace()}], error_logger:error_report(Report), %% NOTE: mustache templates need \ because they are not awesome. Req:respond({500, [{"Content-Type", "text/plain"}], "request failed, sorry\n"}) end.

  继续往下看 mochiweb_example_web:start/1 函数:

mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options1]).

  这里调用函数:mochiweb_http:start/1,传递一个列表,这个列表由三部分组成:

  第一部分:{name, ?MODULE},网站空间,?MODULE为当前模块名称;

  第二部分:{loop, Loop},Loop为上一行代码定义的匿名函数;

  第三部分:由第一行代码返回的元组中的第二个项,也就是:[{ip,{0,0,0,0}},{port,8080}]。

  好了,弄清楚参数,我们就可以看下:mochiweb_http:start/1 函数,代码如下:

%% @spec start(Options) -> ServerRet %% Options = [option()] %% Option = {name, atom()} | {ip, string() | tuple()} | {backlog, integer()} %% | {nodelay, boolean()} | {acceptor_pool_size, integer()} %% | {ssl, boolean()} | {profile_fun, undefined | (Props) -> ok} %% | {link, false} %% @doc Start a mochiweb server. %% profile_fun is used to profile accept timing. %% After each accept, if defined, profile_fun is called with a proplist of a subset of the mochiweb_socket_server state and timing information. %% The proplist is as follows: [{name, Name}, {port, Port}, {active_sockets, ActiveSockets}, {timing, Timing}]. %% @end start(Options) -> mochiweb_socket_server:start(parse_options(Options)).

  从注释来看,这个函数的作用是启动一个mochiweb服务器,关于Options参数的说明也很详细。

  好了,美国空间网站空间,这一篇就到这里,从下一篇开始我们将正式进入mochiweb源码。从这个函数来看,mochiweb源码还是比较工整的,代码注释也比较完善,感谢作者为我们奉献这么好的开源项目,来让我们学习。

  最后,谢谢大家的耐心阅读。好梦。

网友评论
<