如何解决EventSource.onmessage不触发问题?Spring SSE推送前端无法接收事件
SSE onmessage回调不触发问题解决方案
核心原因
你在服务端推送代码中显式指定了自定义事件名称myEvent,而EventSource.onmessage默认仅监听无自定义事件名的默认message事件,因此消息推送成功但不会触发onmessage回调。
可选解决方案
方案1:前端新增自定义事件监听(无需修改后端代码)
在现有JS监听逻辑中新增对myEvent事件的监听即可接收推送数据,同时修正原有代码中onerror回调的变量名错误:
const eventInit = () => { console.log("eventInit called"); const url = 'http://localhost:8080/itf/subscribe'; const eventSource = new EventSource(url); eventSource.onmessage = (event) => { const data = JSON.parse(event.data); console.log('===默认message事件数据==='); console.log(data); } // 新增自定义事件监听 eventSource.addEventListener('myEvent', (event) => { const data = JSON.parse(event.data); console.log('===自定义myEvent事件数据==='); 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 { // 修正原代码变量名错误,将e改为event console.log("onerror", event); } } }
方案2:服务端移除自定义事件名配置(无需修改前端代码)
修改推送逻辑,去掉.name("myEvent")配置,推送默认message事件即可触发前端onmessage回调:
@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 { // 移除name("myEvent")配置 emitter.send(SseEmitter.event().data(map)); } catch (Exception e) { emitter.completeWithError(e); logger_error.error("pushEvent Exception:" + e); deadEmitters.add(emitter); } }); emitters.removeAll(deadEmitters); }
其他优化建议
可以将Controller中subscribe接口的produces配置修改为text/event-stream;charset=UTF-8,避免推送中文时出现乱码。
内容的提问来源于stack exchange,提问作者ringhiosi
相关产品推荐
相关产品推荐

