Erlang的持久/保持HTTP客户端实现
我对Erlang iNet的keep-alive特性以及ibrowse http客户端(最新版本)感到困惑。根据报告: 基于持久连接,有两种模式,“管道”和“保持活动”,它们之间的区别在于,在使用“管道”时,可以在同一连接上发送请求,而无需等待前面的响应。换句话说,当使用“keep alive”时,在同一连接上发送其他请求之前,我们应该等待每个响应 因此,我认为“保持活力”的实现应该是:Erlang的持久/保持HTTP客户端实现,http,erlang,keep-alive,Http,Erlang,Keep Alive,我对Erlang iNet的keep-alive特性以及ibrowse http客户端(最新版本)感到困惑。根据报告: 基于持久连接,有两种模式,“管道”和“保持活动”,它们之间的区别在于,在使用“管道”时,可以在同一连接上发送请求,而无需等待前面的响应。换句话说,当使用“keep alive”时,在同一连接上发送其他请求之前,我们应该等待每个响应 因此,我认为“保持活力”的实现应该是: %% each httpc_handler(gen_server) maintains a persiste
%% each httpc_handler(gen_server) maintains a persistent connection
%% with type of keep-alive
httpc_handler:handle_request(Request, keepalive) ->
%% check if there is request not finished yet
case is_there_old_request() of
true -> queue:in(RQueue, Request);
%% then send the request
false -> gen_tcp:send(Request)
end.
httpc_handler:handle_response(Response) ->
send_back(Response),
case queue:out(RQueue) of
undefined -> ...;
%% send the next request
Request -> gen_tcp:send(Request), ...
end.
但事实上,iNet和ibrowse的实现类似于:
httpc_handler:handle_request(Request, keepalive) ->
%% send without check
gen_tcp:send(Request),
case is_there_old_request() of
true -> queue:in(RQueue, Request);
false -> ...
end.
httpc_handler:handle_response(Response) ->
send_back(Response),
case queue:out(RQueue) of
undefined -> ...;
Request -> receive_next_response
end.
我认为这实际上是没有幂等限制的“管道”模式
因此,我遗漏了代码中的某些内容,或者只是误解了RFC?在查看最新的OTP源代码后,幂等逻辑实际上位于
httpc\u管理器:select\u session
中。如果请求不是幂等的,则返回无连接
,提示系统创建新连接。还有更多的逻辑分散在各处,但我确实在httpc_处理程序中确定了处理管道与保持活动的单独函数。提交已经解决了这个问题,在Erlang/OTP R16中。模块httpc_handler中有两个位置:httpc_handler:handle_call/3和httpc_handler:handle_queue/2,分别处理保持活动和管道。幂等逻辑适用于管道。对于keep-alive,没有幂等限制,但它也发送http请求,而不等待前面请求的响应。我认为这与RFC不符。
httpc_handler:handle_request(Request, keepalive) ->
%% send without check
gen_tcp:send(Request),
case is_there_old_request() of
true -> queue:in(RQueue, Request);
false -> ...
end.
httpc_handler:handle_response(Response) ->
send_back(Response),
case queue:out(RQueue) of
undefined -> ...;
Request -> receive_next_response
end.