【发布时间】:2023-03-22 05:22:01
【问题描述】:
如何让 EventSource.onmessage 工作?
这是我的订阅和推送事件代码:
public SseEmitter subscribe() throws Exception {
SseEmitter emitter = new SseEmitter(1800000L);
emitters.add(emitter);
emitter.onCompletion(() -> {
synchronized (emitters) {
emitters.remove(emitter);
}
});
emitter.onTimeout(() -> {
emitter.complete();
emitters.remove(emitter);
});
return emitter;
}
@Async
public void pushEventMap(Map<String, Object> pushMap) throws IOException {
List<SseEmitter> deadEmitters = new ArrayList<>();
HashMap<String,Object> map = (HashMap<String,Object>) pushMap;
emitters.forEach(emitter -> {
try {
emitter.send(SseEmitter.event().name("myEvent").data(map));
} catch (Exception e) {
emitter.completeWithError(e);
logger_error.error("pushEvent Exception:" + e);
deadEmitters.add(emitter);
}
});
emitters.removeAll(deadEmitters);
}
上述服务的控制器是:
@RequestMapping(value = "/subscribe", produces = "text/event-stream")
public ResponseEntity<SseEmitter> subscribe() throws Exception {
final SseEmitter emitter = eventService.subscribe();
return new ResponseEntity<>(emitter, HttpStatus.OK);
}
@RequestMapping(value = "/publish")
public void publish() throws IOException {
eventService.pushEventMap(pushMap);
}
我想让客户端通过js接收事件推送的数据。
const eventInit = () => {
console.log("eventInit called");
const url = 'http://localhost:8080/itf/subscribe';
const eventSource = new EventSource(url);
var httpRequest = new XMLHttpRequest();
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('===');
console.log(data);
}
eventSource.onopen = (event) => {
console.log('sse open');
console.log(event);
}
eventSource.onerror = (event) => {
if (event.readyState == EventSource.CLOSED) {
console.log('sse close');
} else {
console.log("onerror", e);
}
}
}
在这种状态下,如果我通过邮递员发送事件生成数据,sse open 会出现在控制台上。
但是,事件的结果并没有显示出来。
如果我通过url直接访问/itf/subscribe,则事件的结果会显示在屏幕上。但是,我没有通过event.onmessage 收到事件的结果。
我想要的是引发一个事件,然后通过onmessage函数接收事件的结果。
我想知道如何获得事件的结果。
最好的问候
【问题讨论】:
标签: java spring web server-sent-events