我正在尝试为我的应用程序实现SSE。我的客户端是Angular 4应用程序,我使用EventSourcePolyfill(也可以在IE中使用)。我的服务器端是Spring,我也使用Spring SseEmitter。
我基于客户端特定用户事件打开一个新的SSE连接。我可以看到请求到达服务器,SSE事件被记录下来,我也能看到响应正在创建。我想要以json格式发送响应。我基本上是尝试发送数据更新,并创建带有更新数据的json。但是SSE从未到达浏览器,只进入了Eventsource.onerror方法。因此,浏览器一直在重试。
在Chrome的开发工具-网络选项卡中,我可以看到SSE请求显示为等待几秒钟,然后更改为取消。
这里是我放置代码片段和错误信息的地方。
Angular 代码:
let eventSource = new EventSourcePolyfill('v1/sse/getInfiniteMessages', {
// headers: {
// 'Accept': 'text/event-stream'
// },
heartbeatTimeout:180
});
eventSource.onmessage = (eventResponse => {
console.log("Message from event source is :: " + eventResponse);
console.log("JSON from event source is :: " + eventResponse.data);
});
eventSource.onopen = (a) => {
// Do stuff here
console.log("Eventsource.onopen.. " + JSON.stringify(a));
};
eventSource.onerror = (e) => {
// Do stuff here
console.log("Eventsource.onerror.. Exception is:: " + JSON.stringify(e));
if (e.readyState == eventSource.CLOSED) {
console.log('event source is closed');
eventSource.close();
}
else {
console.log("Not a event source closed error");
}
}
Spring(服务器端)
控制器:
@RequestMapping(method = RequestMethod.GET, value = "/getInfiniteMessages")
public SseEmitter getInfiniteMessages() {
return iSSEService.getInfiniteMessages();
}
服务:
public SseEmitter getInfiniteMessages(String chatRefId) {
logger.info("In SSEService.. getInfiniteMessages method.." );
boolean stopSSE = false;
while (!stopSSE) {
try {
ResponseVo responseVO = new ResponseVo();
responseVO = getData();
// Gson gson = new Gson();
// String sseMessage = gson.toJson(responseVO);
// logger.info("sseMessage to send: " + sseMessage);
// emitter.send(sseMessage , MediaType.APPLICATION_JSON);
emitter.send(responseVO);
Thread.sleep(30000);
//stopSSE = true;
} catch (Exception e) {
e.printStackTrace();
emitter.completeWithError(e);
//return;
}
}
/*for (int i = 0; i < 100; i++) {
try {
emitter.send(i + " - Message", MediaType.TEXT_PLAIN);
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
emitter.completeWithError(e);
//return;
}
}*/
return emitter;
}
有几行注释掉的代码,是我尝试过但没有成功的。
注意:在服务端代码中,如果我取消注释for循环(运行100次),sse文本会到达浏览器,但我想发送包含数据更新的json。我尝试将对象创建为json并作为文本发送,但这并没有帮助。
错误:
从onError方法的console.log中看到:
Not a event source closed error
Eventsource.onerror.. Exception is:: {"type":"error","target":{"listeners":{"data":{}},"url":"/v1/sse/getInfiniteMessages","readyState":0,"withCredentials":false}}
浏览器错误:
core.es5.js:1020 ERROR Error: No activity within 45000 milliseconds. Reconnecting.
at eventsource.js:363
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:425)
at Object.onInvokeTask (core.es5.js:3881)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:192)
at webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:499)
at ZoneTask.invoke (zone.js:488)
at timer (zone.js:2040)
希望在这里得到朋友们的帮助,来解决我的问题。
POST /notify
,但您也可以使用定期方法、线程或您需要的任何方法。您还可以选择性地向哪些发射器推送(您不必一次性向所有发射器推送)。关于发送JSON响应,它应该会自动转换为JSON。请参阅此完整教程以获得更详细的解释:https://golb.hplar.ch/p/Server-Sent-Events-with-Spring - ESala