Jersey SSE EventOutput 未关闭时不会将写入的内容发送给客户端

3

我有一个使用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() 的变通方法,可以帮助刷新消息,但当然会有关闭连接的副作用。虽然连接会自动从客户端重新创建,但我只是想弄清楚为什么在我的情况下需要关闭? 是否与一些标准响应流缓冲区大小有关?我的消息是由用户输入的聊天字符串,长度甚至可能只有 1 个字符。 我正在使用 GlassFish 服务器 4 和 jersey 版本 2.9.1 jars。浏览器是 chrome。
3个回答

3
我与您有相同的问题,在使用wireshark后终于找到了解决方法。实际上,数据只在HTTP响应正文中发送,而没有被流式传输或分块处理。换句话说,如果未显式调用eventOutput.close,则不会发送该数据。
首先,请检查代理(如果您正在使用)以确保该方面没有缓冲区。
最后,请检查您的java webapp是否有任何过滤器可能会收集响应。在我的情况下,是Dropwizard中的gzip过滤器阻止了TCP数据包的发送。
我在JERSEY-jira中详细写了一些内容。

1
我曾经遇到过同样的问题,我在我的ResourceConfig.java文件中解决了这个问题,方法是删除。如果你也有这个问题,请参考。
EncodingFilter.enableFor(this, GZipEncoder.class);

-2

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

这个回答和我的问题完全无关。正如我之前提到的,如果我在服务器上进行显式调用关闭或尝试关闭服务器,则会在客户端收到消息。顺便说一句,即使eventsource不是jquery对象,我也会在调用其上的方法之前将其包装起来,就像$(source)一样。原始问题中给出的Jquery代码非常好。只是服务器无法在没有关闭调用的情况下推送。 - Mithun Ruikar
明白了。我尝试使用你展示的jQuery包装器,但无法正常工作。我不得不使用本地的onMessage处理程序。此外,我正在运行Glassfish推广版本b08,其中包括Jersey 2.10.1。 - Baldy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接