使用inet检测HTTP关闭

时间:2009-12-30 12:22:47

标签: http erlang mochiweb inet

在我的mochiweb应用程序中,我正在使用长时间持有的HTTP请求。我想检测与用户的连接何时死亡,我想通过执行以下操作来做到这一点:

Socket = Req:get(socket),
inet:setopts(Socket, [{active, once}]),
receive
     {tcp_closed, Socket} ->
             % handle clean up
     Data ->
             % do something 
end.

这适用于:用户关闭其标签/浏览器或刷新页面。然而,当互联网连接突然死亡(说wifi信号突然丢失),或者当浏览器异常崩溃时,我无法检测到tcp关闭。

我错过了什么,或者还有其他方法可以实现这个目标吗?

3 个答案:

答案 0 :(得分:2)

有一个TCP keepalive protocol,可以通过选项inet:setopts/2下的{keepalive, Boolean}启用。

我建议你不要使用它。保持活动超时和最大重试往往是系统范围的,毕竟它是可选的。在协议级别使用超时更好。

HTTP协议具有status code Request Timeout,如果它似乎已经死了,您可以将其发送给客户端。

查看可用于超时等待数据的接收块中的after子句,或使用定时器模块,或使用erlang:start_timer/3。它们都具有不同的性能特征和资源成本。

答案 1 :(得分:1)

TCP上没有默认的“保持活动”(但可以是enabled if supported)协议:如果没有数据交换时出现连接故障,则会转换为“静默失败”。您需要自己解决此类故障,例如实施某种形式的连接探测。

这对HTTP有何影响? HTTP是无状态协议 - 这意味着每个请求都是彼此独立的。 HTTP的“保持活动”功能不会改变,即“静默失败”仍然可能发生。

仅在交换数据时才能检测到这种情况(或启用TCP Keep Alive时)。

答案 2 :(得分:0)

我建议通过HTTP chunked-encoding发送应用程序级别保持活动消息。让您的客户端/服务器足够智能,以了解保持活动消息,如果它们准时到达或关闭并再次重新建立连接,则忽略它们。