【问题标题】:Detecting HTTP close using inet使用 inet 检测 HTTP 关闭
【发布时间】:2010-12-31 02:20:41
【问题描述】:

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

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

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

是我遗漏了什么,还是有其他方法可以做到这一点?

【问题讨论】:

    标签: http erlang mochiweb inet


    【解决方案1】:

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

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

    HTTP 协议有status code Request Timeout,如果它看起来死了,您可以将其发送给客户端。

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

    【讨论】:

    • 我考虑过使用 after 子句,但在这种情况下,我的进程可能是一个休眠进程。 after 子句仍然适用于休眠进程吗?
    • 不,不会。当消息被发送给休眠进程时,它会被唤醒。没有休眠超时,因此会向您发送延迟消息以唤醒。
    【解决方案2】:

    没有基于 TCP 的默认“保持活动”(但可以是 enabled if supported)协议:如果在没有数据交换时出现连接故障,这将转换为“静默故障”。您需要自己考虑这种类型的失败,例如实现某种形式的连接探测。

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多