除非关闭,否则Jersey SSE Eventoutput写入不会进入客户端

时间:2014-07-30 16:00:09

标签: java-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());
});

这是使用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。

3 个答案:

答案 0 :(得分:3)

我和你有同样的问题,并在打开wireshark之​​后终于明白了。也就是说,数据仅在HTTP响应正文中发送,而不是流式传输/分块。换句话说,如果eventOutput.close未被明确调用,则不会发送。

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

最后,检查您的java webapp上是否有可能正在收集回复的任何过滤器。在我的例子中,Dropwizard中的gzip过滤器正在保存TCP数据包。

我在JERSEY-jira

处写了更详细的内容

答案 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);