首页 > 解决方案 > 无法使用 SSE 发送消息(Java Servlet + ES6 JS)

问题描述

我试图在此视频中制作 SSE 示例https://www.youtube.com/watch?v=rhCKCKD0KnA

    response.setContentType("text/event-stream");
    response.setCharacterEncoding("UTF-8");

    PrintWriter printWriter = null;

    while(true) {

        try {
            double rnd = Math.random() * 10000;

            printWriter = response.getWriter();
            printWriter.print("Rnd: " + rnd);

            response.flushBuffer();


            Thread.sleep(5000);

        }
        catch(IOException | InterruptedException e) {
            e.printStackTrace();

            printWriter.close();

            break;
        }


    }

和客户端

    window.onload = function () {

        startButton.onclick = () => {
            eventSource = new EventSource('http://localhost:8080/byteslounge-1/sse_test');

            eventSource.onopen = () => {
                displayTextArea.value += 'connected...' + '\n';
            };

            eventSource.onmessage = (message) => {
                displayTextArea.value += message.data + '\n\n';
            };

            eventSource.onerror = () => {
                displayTextArea.value += 'error occured...' + '\n';
            };

            startButton.disabled = true;
        };

        takeMsg.onclick = () => {
            eventSource.onmessage = (message) => {
                displayTextArea.value += message.data + '\n\n';
            };
        };

        stopButton.onclick = () => {
            eventSource.close();
            startButton.disabled = false;
        };

        clearText.onclick = () => {
            displayTextArea.value = '';
        }

    }

连接正常,但无法接收 onMessage 中的任何数据。服务器/客户端上没有错误/警告。我正在使用 FF 64 位最新版本/JDK 1.8/Payara。

标签: javahtmljakarta-eelong-pollingpayara

解决方案


I don't see any obvious problem in your code. However, when using Payara 5, I recommend using JAX-RS SSE API instead of coding it yourself in a servlet.

See an example and guide here: http://ridingthecrest.com/blog/2017/02/22/jax-rs-2_1-new-feature-introduction.html

An alternative of your server endpoint with JAX-RS SSE:

@Path("server-sent-events")
@Singleton
public class ServerSentEventsResource {

    @GET
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public void getMessageQueue(@Context SseEventSink eventSink, @Context Sse sse) {

      while(true) {

        try {
            double rnd = Math.random() * 10000;

            eventSink.send(sse.newEvent("custom-message"));

            Thread.sleep(5000);

        }
        catch(IOException | InterruptedException e) {
            e.printStackTrace();

            printWriter.close();

            break;
        }
      }
    }
}

Also test the server endpoint with an generic SSE client, e.g. curl supports SSE and prints incoming events as they come. If that works, then your javascript client has an error.


推荐阅读