简体   繁体   English

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

[英]Java spring SseEmitter/ResponseBodyEmitter: detect browser reloads

I'm using server-side events (SSE) in Java Spring. 我在Java Spring中使用服务器端事件(SSE)。 Whenever a new client subscribes to the events service I execute the following code at the REST controller: 每当新客户端订阅事件服务时,我在REST控制器上执行以下代码:

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

Then, whenever an event needs to be notified to the clients I execute: 然后,每当需要将事件通知给我执行的客户端时:

 for (ResponseBodyEmitter emitter: emitters) {
        emitter.send("Message #1");
 }

The problem is that when one of the clients reloads the browser, the emitter does not get completed (as I expected), and I get a broken pipe exception when calling the code above. 问题是当其中一个客户端重新加载浏览器时,发射器没有完成(正如我所料),并且在调用上面的代码时我得到一个损坏的管道异常。 Only after this exception is triggered I see the emitter being completed. 只有在触发此异常后,我才会看到发射器已完成。

Is there a way to solve this problem? 有没有办法解决这个问题?

When the browser reloads, it will establish a new EventSource to your server, right? 当浏览器重新加载时,它会为您的服务器建立一个新的EventSource,对吧? Your problem is with the old one, which has no client endpoint anymore. 您的问题是旧的问题,它不再具有客户端端点。

I suggest you try to detect that it is the same client connecting, and then explicitly call complete on the old emitter. 我建议你尝试检测它是同一个客户端连接,然后在旧发射器上显式调用完成。

In my case I can detect this based on a token which the EventSource passes in as a URL parameter. 在我的情况下,我可以根据EventSource传入的令牌检测到这一点作为URL参数。 When I hook the newly created emitter to a "user object", I make sure to complete the previous emitter before assigning the new to the user field variable. 当我将新创建的发射器挂钩到“用户对象”时,我确保在将新的发射器分配给用户字段变量之前完成前一个发射器。

From your code, it seems you have a list or set of emitters. 从您的代码中,您似乎有一个列表或一组发射器。 Can you maybe make it a map instead, where you have some client identity as the key, and the emitter as the value? 你可以把它改成地图,你有一些客户端身份作为密钥,发射器作为值吗?

I can't tell you exactly what piece of information to use as a client identity, since it all depends on your application. 我无法准确地告诉您要用作客户身份的信息,因为这完全取决于您的应用程序。 In my case it is a JWT token, but you could perhaps simply create a client numbering scheme... 在我的例子中,它是一个JWT令牌,但你可以简单地创建一个客户编号方案......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM