【问题标题】:How do I get EventSource.onmessage to work?如何让 EventSource.onmessage 工作?
【发布时间】: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


    【解决方案1】:

    代码没有问题,实际问题是当我写响应客户端时,我的响应消息应该如下所示。

    PrintWriter out = response.write("data: message"+value+"\n\n");
    out.flush(); //don't forget to flush
    

    在我的代码中,我缺少响应对象中的最后一部分“\n\n”,因此 javascript 中的 source.onmessage(datalist) 没有被命中。

    【讨论】:

    • 这与这个问题有关吗?我在问题中没有看到response.write() 行。
    【解决方案2】:
        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);
    

    这是正常的工作!

    【讨论】:

    • 这是对您问题的回答吗?它看起来更像是您应该编辑问题并添加到那里的附加信息?
    • 我应该回答有问题的代码吗? @达伦库克
    猜你喜欢
    • 2011-05-04
    • 2011-04-07
    • 2011-07-27
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多