在我的mochiweb应用程序中,我正在使用长时间持有的HTTP请求。我想检测与用户的连接何时死亡,我想通过执行以下操作来做到这一点:
Socket = Req:get(socket),
inet:setopts(Socket, [{active, once}]),
receive
{tcp_closed, Socket} ->
% handle clean up
Data ->
% do something
end.
这适用于:用户关闭其标签/浏览器或刷新页面。然而,当互联网连接突然死亡(说wifi信号突然丢失),或者当浏览器异常崩溃时,我无法检测到tcp关闭。
我错过了什么,或者还有其他方法可以实现这个目标吗?
答案 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发送应用程序级别保持活动消息。让您的客户端/服务器足够智能,以了解保持活动消息,如果它们准时到达或关闭并再次重新建立连接,则忽略它们。