6

在我的 mochiweb 应用程序中,我使用了一个长期持有的 HTTP 请求。我想检测与用户的连接何时消失,我想出了如何做到这一点:

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

这适用于:用户关闭他的选项卡/浏览器或刷新页面。但是,当互联网连接突然中断(比如wifi信号突然丢失),或者浏览器异常崩溃时,我无法检测到tcp关闭。

我错过了什么,还是有其他方法可以实现这一目标?

4

3 回答 3

2

有一个TCP keepalive 协议,可以inet:setopts/2在选项下启用它{keepalive, Boolean}

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

HTTP 协议有状态码请求超时,如果它看起来死了,您可以将其发送给客户端。

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

于 2009-12-30T14:51:28.163 回答
1

TCP上没有默认的“保持活动状态”(但如果支持,可以启用)协议:如果在没有数据交换时出现连接故障,这将转换为“静默故障”。您需要自己解决此类故障,例如实施某种形式的连接探测。

这对 HTTP 有何影响?HTTP 是一种无状态协议——这意味着每个请求都是相互独立的。HTTP 的“保持活动”功能不会改变,即“静默故障”仍然可能发生。

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

于 2009-12-30T13:07:17.960 回答
0

我建议通过 HTTP 分块编码发送应用程序级别的保持活动消息。让您的客户端/服务器足够聪明,以了解保持活动消息,并在它们按时到达或关闭并重新建立连接时忽略它们。

于 2010-11-04T03:57:24.460 回答