How do I get EventSource.onmessage to work?
Here is my subscribe and pushevent code:
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);
}
The controller for the above service is:
@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);
}
I want the client to receive the data of event push through 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);
}
}
}
In this state, if I send event-generating data through postman, sse open
appears on the console.
However, the result of the event is not displayed.
If I directly access /itf/subscribe
through the url, the result of the event is displayed on the screen. However, I am not receiving the result of the event through event.onmessage
.
What I want is to raise an event, and then receive the result of the event through the onmessage function.
I am wondering how can I get the result of the event.
best regards
CodePudding user response:
There is no issue with code, the actual issue is when I am writing response to client my response message should look like as below.
PrintWriter out = response.write("data: message" value "\n\n");
out.flush(); //don't forget to flush
In my code I was missing the last part "\n\n" in response object so source.onmessage(datalist) in javascript didn't get hit.
CodePudding user response:
eventSource.addEventListener('myEvent', function (event) {
console.log(event);
const data = JSON.parse(event.data);
console.log('addEventListener');
console.log(data);
// console.log(data.siteCode);
eventEffect(data);
}, false);
this is normally work!