简体   繁体   English

服务器发送的事件失去连接

[英]Server-sent event lost connection

I'm following this tutorial and I'm putting the returned data on console log in Chrome. 我正在按照本教程进行操作 ,并将返回的数据放在Chrome的控制台日志中。 Here is my code on client side: 这是我在客户端的代码:

$(document).ready(function() {  

  //check for browser support
  if(typeof(EventSource)!=="undefined") {

    var source = new EventSource("URL/sse");
    //detect message receipt       
    source.addEventListener("message", function(e) {
        console.log(e.data);            
    }, false);

    source.addEventListener("open", function(e) {
        console.log("Connection was opened.");
    }, false);


    source.addEventListener("error", function(e) {
        if (e.readyState == EventSource.CLOSED) {
            console.log("Connection lost.");
        }            
    }, false);
  }
  else {
    // No support
  }
});

The data is ok. 数据还可以。 When I access the webpage, my console log is opening and closing the connection every 3 seconds: 当我访问该网页时,控制台日志每3秒打开和关闭一次连接:

mypage.js:39 Connection was opened.
mypage.js:15 [{"John":"1","Doe":"2"}]
mypage.js:44 Error - Connection lost.
// 3 seconds
mypage.js:39 Connection was opened.
mypage.js:15 [{"John":"1","Doe":"2"}]
mypage.js:44 Error - Connection lost.
// 3 seconds
mypage.js:39 Connection was opened.
mypage.js:15 [{"John":"1","Doe":"2"}]
mypage.js:44 Error - Connection lost.
...

Here is my server-side code: 这是我的服务器端代码:

@Singleton
@Path("/sse")
public class SSEResource {

  @GET
  @Produces(SseFeature.SERVER_SENT_EVENTS)
  public EventOutput getServerSentEvents() {
    final EventOutput eventOutput = new EventOutput();

    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                final OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
                eventBuilder.name("message");

                final String myString = getData.toString(); // Some data from db

                eventBuilder.data(String.class, myString);

                final OutboundEvent event = eventBuilder.build();
                eventOutput.write(event);

            } catch (Exception e) {
                throw new RuntimeException("Error when writing the event.",
                        e);
            } finally {

                try {
                    eventOutput.close();
                } catch (IOException ioClose) {
                    throw new RuntimeException(
                            "Error when closing the event output.", ioClose);
                }
            }
        }
    }).start();
    return eventOutput;
  }
}

From what I understand, the connection should remain open until the client decided to close it. 据我了解,该连接应保持打开状态,直到客户端决定关闭它为止。 What am I doing wrong? 我究竟做错了什么? Is that correct? 那是对的吗?

Your server code is closing the EventOutput. 您的服务器代码正在关闭EventOutput。

           try {
                eventOutput.close();
            } catch (IOException ioClose) {
                throw new RuntimeException(
                        "Error when closing the event output.", ioClose);
            }

This causes the client to reconnect and the process starts again. 这将导致客户端重新连接,并且该过程再次开始。

I'm not 100% sure what you are doing. 我不确定您在做什么。 If you want to send more data in the thread, you need to not close the EventOutput. 如果要在线程中发送更多数据,则无需关闭EventOutput。

According to the specification you can send a HTTP 204 No Content response code to prevent the client from reconnecting, I'm not sure how to do this using Jersey SSE though. 根据规范,您可以发送HTTP 204 No Content响应代码以防止客户端重新连接,但是我不确定如何使用Jersey SSE来执行此操作。 I was searching for the answer when I came across this question. 当我遇到这个问题时,我正在寻找答案。

In your case you could send a message that causes the client to close the connection, or prevents it from reconnecting. 在您的情况下,您可以发送一条消息,使客户端关闭连接或阻止其重新连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM