2010年5月20日星期四

mochiweb 不一定每个请求是一个新的process(转)

转:http://approach.javaeye.com/blog/547638

今天试了一下mochiweb,这个东东的文档实在是少的可怜,推荐一个不错的tutorial:

http://erlang-china.org/start/mochiweb_intro.html

做了一个简单的comet测试,在firefox下浏览时发现每个http请求处理的process id固定在2个,而且进程字典的数据也可以跨请求共享,找了下mochiweb的源码,发现其在http请求结束时,支持tcp连接复用(http1.1),代码如下:

mochiweb_http.erl

Erlang代码
  1. after_response(Body, Req) ->
  2. Socket = Req:get(socket),
  3. case Req:should_close() of
  4. true ->
  5. gen_tcp:close(Socket),
  6. exit(normal);
  7. false ->
  8. Req:cleanup(),
  9. ?MODULE:loop(Socket, Body)
  10. end.

mochiweb_request.erl

Erlang代码
  1. %% @spec should_close() -> bool()
  2. %% @doc Return true if the connection must be closed. If false, using
  3. %% Keep-Alive should be safe.
  4. should_close() ->
  5. ForceClose = erlang:get(mochiweb_request_force_close) =/= undefined,
  6. DidNotRecv = erlang:get(mochiweb_request_recv) =:= undefined,
  7. ForceClose orelse Version < {1, 0}
  8. %% Connection: close
  9. orelse get_header_value("connection") =:= "close"
  10. %% HTTP 1.0 requires Connection: Keep-Alive
  11. orelse (Version =:= {1, 0}
  12. andalso get_header_value("connection") =/= "Keep-Alive")
  13. %% unread data left on the socket, can't safely continue
  14. orelse (DidNotRecv
  15. andalso get_header_value("content-length") =/= undefined
  16. andalso list_to_integer(get_header_value("content-length")) > 0)
  17. orelse (DidNotRecv
  18. andalso get_header_value("transfer-encoding") =:= "chunked").

So, it's clear now.

没有评论: