Java spring SseEmitter/ResponseBodyEmitter : detect browser reloads

标签 java spring

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

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

然后,每当需要将事件通知给我执行的客户端时:
 for (ResponseBodyEmitter emitter: emitters) {
        emitter.send("Message #1");
 }

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

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

最佳答案

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

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

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

从您的代码中,您似乎有一个或一组发射器。你能不能把它变成一个 map ,你有一些客户端身份作为键,发射器作为值?

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

关于Java spring SseEmitter/ResponseBodyEmitter : detect browser reloads,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34530544/

相关文章:

java - Web 模块之间是否共享线程?

Java查找与某个字符等价的上标字符

java - 需要使用 XSLT 从 XML 生成平面文件中的自定义订单

java - 使用 Spring MVC 和 JIBX 编码不同的类

java - 具有 Kotlin 协程的函数是否可以等待完成并返回到 Java 类?

java - 为什么要在 Java 中使用嵌套的 InvokeLater 调用?

java - JPA 避免在保存对象时对关联对象进行额外的读取调用

java - 如何在 Spring Data @Repository 查找方法中指定默认排序?

java - JsonParseException : Invalid UTF-8 middle byte 0x20 with MockMVC and Maven

java - 在 spring mvc 中处理包装的异常