我有 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/