jakarta-ee - Jersey SSE Eventoutput 写入不会发送到客户端,除非关闭

标签 jakarta-ee servlets jersey-2.0

我有 jquery 客户端期待来自 java servlet/JAX-RS 服务器的 Jersey SSE 事件。

我有这个客户端代码向服务器发起请求

var source = new EventSource("api/chat");
$(source).on("message", function (evt) {
    var chatMsg = JSON.parse(evt.originalEvent.data);    
    $("#chat").val(chatMsg.userid + ": " + chatMsg.msg + "\n" + $("#chat").val());
});

这是使用事件输出推送消息的服务器代码

JsonObject obj = Json.createObjectBuilder()
                .add("userid", userid)
                .add("msg", msg)
                .build();
OutboundEvent evt = new OutboundEvent.Builder()
                .mediaType(MediaType.APPLICATION_JSON_TYPE)
                .data(JsonObject.class, obj)
                .build();   

eventOutput.write(evt);
eventOutput.close();

如果不使用 eventoutput.close(),客户端将不会收到任何响应。

根据文档,这种关闭不是必需的,或者至少没有在任何地方提及。但是没有这些消息就会排队,只有当我尝试关闭服务器时它们才会被传送。那很奇怪。 我找到了 close() 的解决方法,它有助于刷新消息,但当然会产生关闭连接的副作用。虽然 Connection 是从客户端自动重新创建的,但我只是想了解为什么在我的情况下需要关闭? 有没有人遇到过类似的问题?

是否与某些标准响应流缓冲区大小有关?我的消息是用户输入的聊天字符串,长度甚至可以是 1 个字符。

我使用的是 GlassFish server 4 和 jersey 2.9.1 版本的 jar。浏览器是 chrome。

最佳答案

我遇到了和你一样的问题,打开wireshark后终于弄明白了。即,数据仅在 HTTP 响应主体上发送,而不是流式传输/分块。换句话说,如果未明确调用 eventOutput.close,则不会发送它。

首先,检查您的代理(如果您正在使用代理)以确保那一侧没有缓冲。

最后,检查您的 java webapp 上是否有任何过滤器可能正在收集响应。在我的例子中,是 Dropwizard 中的 gzip 过滤器阻止了 TCP 数据包的发送。

我在 JERSEY-jira 写了更详细的内容

关于jakarta-ee - Jersey SSE Eventoutput 写入不会发送到客户端,除非关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25041542/

相关文章:

html - 在 JSP 应用程序中基于 CSS 实现参数化外观的最佳方式是什么?

javascript - 这是否被视为 POST 或 GET 请求?

java - HK2 与 Jersey 2 和 Apache Shiro 的依赖注入(inject)

java - 在 Jersey 中实现不同的 URL 路径

java - 为什么 Jersey 不尊重动态绑定(bind)过滤器中的优先级?

java - 如何将列表发送到请求它的 jsp?

database - 如何维护来自两个不同数据库的记录的唯一ID?

jakarta-ee - Glassfish 设置并发批处理作业的最大数量

jakarta-ee - 如果有异步方法仍在运行,无状态 session 是否会被另一个线程使用?

java - 从文件中读取?