根据文件:
当远程客户端离开时,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也提出了类似的问题,但在这种情况下,文档中的解决方案似乎根本不起作用。
1条答案
按热度按时间643ylb081#
为后人张贴这一点,因为似乎很少有明确写的主题:
SSE没有提供一种机制,让客户端告诉服务器它已经断开连接,TCP也不包含此信息。为了正确,服务器必须发送响应,只要可以(即)。直到服务器超时)。
正确的解决方案是每隔X秒在客户端执行一次'heartbeat'调用,告诉服务器“是的,我还在这里”,然后清除未能及时报告的连接。
Websockets不需要这个,因为它们提供了一种机制来提供心跳(PING/PONG)。