我让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());
});
这是使用eventoutput
推送消息的服务器代码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服务器4和jersey 2.9.1版本的jar。浏览器是chrome。
答案 0 :(得分:3)
我和你有同样的问题,并在打开wireshark之后终于明白了。也就是说,数据仅在HTTP响应正文中发送,而不是流式传输/分块。换句话说,如果eventOutput.close
未被明确调用,则不会发送。
首先,检查您的代理(如果您正在使用代理),以确保该方没有缓冲。
最后,检查您的java webapp上是否有可能正在收集回复的任何过滤器。在我的例子中,Dropwizard中的gzip过滤器正在保存TCP数据包。
处写了更详细的内容答案 1 :(得分:0)
我有同样的问题, 我在ResourceConfig.java中解决了删除,如果你有:
EncodingFilter.enableFor(this, GZipEncoder.class);
答案 2 :(得分:-1)
EventSource
不是jQuery对象(除非您正在加载某种插件)。
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
// Connection was opened.
}, false);
source.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
// Connection was closed.
}
}, false);