HTTP 流媒体和 HTTP 长轮询的 SockJS 传输需要连接保持比平时更长时间的开放。关于这些技术的概述,请看 这篇博文。
在 Servlet 容器中,这是通过 Servlet 3 异步支持完成的,它允许退出 Servlet 容器线程,处理一个请求,并继续从另一个线程写到响应。
一个具体的问题是,Servlet API 并没有为一个已经离开的客户端提供通知。参见 eclipse-ee4j/servlet-api#44。然而,Servlet 容器在随后试图写入响应时引发了一个异常。由于 Spring 的 SockJS 服务支持服务器发送的心跳(默认情况下每 25 秒一次),这意味着客户端断开连接通常会在这个时间段内被检测到(如果消息发送得更频繁,也可以更早)。
:::info 因此,网络 I/O 故障可能会因为客户端断开连接而发生,这可能会使日志中充满不必要的堆栈痕迹。Spring 尽力识别这种代表客户端断开连接的网络故障(具体到每台服务器),并通过使用专用的日志类别 DISCONNECTED_CLIENT_LOG_CATEGORY(在 AbstractSockJsSession 中定义)来记录一个最小的消息。如果你需要看到堆栈跟踪,你可以将该日志类别设置为 TRACE。 :::