我正在关注this tutorial我将返回的数据放在 Chrome 的控制台日志中。这是我在客户端的代码:
$(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
}
});
数据没问题。当我访问网页时,我的控制台日志每 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.
...
这是我的服务器端代码:
@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;
}
}
据我了解,连接应保持打开状态,直到客户端决定关闭它。我究竟做错了什么?这是正确的吗?
最佳答案
您的服务器代码正在关闭 EventOutput。
try {
eventOutput.close();
} catch (IOException ioClose) {
throw new RuntimeException(
"Error when closing the event output.", ioClose);
}
这会导致客户端重新连接并且进程再次开始。
我不是 100% 确定你在做什么。如果要在线程中发送更多数据,则不需要关闭EventOutput。
根据规范,您可以发送 HTTP 204 No Content 响应代码来阻止客户端重新连接,但我不确定如何使用 Jersey SSE 来执行此操作。当我遇到这个问题时,我正在寻找答案。
在您的情况下,您可以发送一条消息,导致客户端关闭连接,或阻止其重新连接。
关于java - 服务器发送的事件丢失连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31987130/