Java spring SseEmitter/ResponseBodyEmitter:检测浏览器重新加载

Dam*_*les 6 java spring

我在Java Spring中使用服务器端事件(SSE).每当新客户端订阅事件服务时,我在REST控制器上执行以下代码:

SseEmitter emitter = new SseEmitter(-1L);
emitter.onCompletion(() -> {
        logger.debug(TAG + "Emitter completed.");
        emitters.remove(emitter);
    });
return emitter;
Run Code Online (Sandbox Code Playgroud)

然后,每当需要将事件通知给我执行的客户端时:

 for (ResponseBodyEmitter emitter: emitters) {
        emitter.send("Message #1");
 }
Run Code Online (Sandbox Code Playgroud)

问题是当其中一个客户端重新加载浏览器时,发射器没有完成(正如我所料),并且在调用上面的代码时我得到一个损坏的管道异常.只有在触发此异常后,我才会看到发射器已完成.

有没有办法解决这个问题?

Lei*_*ohn 4

当浏览器重新加载时,它会为您的服务器建立一个新的EventSource,对吧?您的问题在于旧的,它不再有客户端端点。

我建议您尝试检测是否是同一个客户端连接,然后在旧发射器上显式调用完成。

就我而言,我可以根据 EventSource 作为 URL 参数传入的令牌来检测这一点。当我将新创建的发射器连接到“用户对象”时,我确保在将新发射器分配给用户字段变量之前完成前一个发射器。

从您的代码来看,您似乎有一个或一组发射器。您是否可以将其制作为地图,其中将一些客户端身份作为键,将发射器作为值?

我无法准确告诉您使用哪一条信息作为客户端身份,因为这完全取决于您的应用程序。就我而言,它是一个 JWT 令牌,但您也许可以简单地创建一个客户端编号方案......