spring SseEmitter不会在客户端断开连接时引发IOException

m1m5dgzv  于 2023-06-21  发布在  Spring
关注(0)|答案(1)|浏览(490)

根据文件:
当远程客户端离开时,Servlet API不提供任何通知。因此,在流式传输到响应时,无论是通过SseEmitter还是React类型,定期发送数据都很重要,因为如果客户端断开连接,写入就会失败。
这应该在调用SseEmitter::send()方法时显示为IOException,但是我使用的是Spring + Embedded Tomcat 9.0.64,这个异常永远不会抛出,因此不可能清理未使用的发射器。
我使用以下代码:

try {
    emitter.send(SseEmitter.event()
            .id(event.getId().toString())
            .name("update")
            .data(data)
    );
} catch (Exception e) {
    logger.info("Dead emitter detected. Removing...");
    deadEmitters.add(emitter);
}

在这种情况下,异常永远不会被触发。我做错什么了吗?
我期待着一个异常被抛出,按照文件。
Another question也提出了类似的问题,但在这种情况下,文档中的解决方案似乎根本不起作用。

643ylb08

643ylb081#

为后人张贴这一点,因为似乎很少有明确写的主题:
SSE没有提供一种机制,让客户端告诉服务器它已经断开连接,TCP也不包含此信息。为了正确,服务器必须发送响应,只要可以(即)。直到服务器超时)。
正确的解决方案是每隔X秒在客户端执行一次'heartbeat'调用,告诉服务器“是的,我还在这里”,然后清除未能及时报告的连接。
Websockets不需要这个,因为它们提供了一种机制来提供心跳(PING/PONG)。

相关问题