1

I have a servlet serving SSE data

writer.write("data: Time is ");
writer.write(Calendar.getInstance().getTime().toString()+"\n\n");
System.out.println("Error state of the stream: " + writer.checkError()); //prints false
response.flushBuffer();

And here is my javascript code:

var eventSource = null;

function start() {
    if (!!window.EventSource) {
        eventSource = new EventSource("SSESyncServlet");
    } else {
        // Result to xhr polling :(
    }

    eventSource.addEventListener('message', function(event) {
        document.getElementById('dataFromServer').innerHTML = event.data;
    });

    eventSource.addEventListener('open', function(e) {
        console.log("connection opened event");
    });

    eventSource.addEventListener('error', function(e) {
        console.log("connection error event");
    });
}

Not sure what's causing it but I get the error event in the javascript after the message event.

UPDATE 1:

After the suggestion from the comments below that I need to use Async servlets, the server side code is modified.

    final AsyncContext aCtx = request.startAsync();

    final PrintWriter writer = response.getWriter();
    System.out.println("Request Received");

    Runnable runnable = new Runnable() {
        @Override
        public void run() {

            writer.write("data: Time is \n");
            writer.write("data: "+Calendar.getInstance().getTime().toString()+"\n\n");
            System.out.println("Error state of the stream: " + writer.checkError());
            writer.flush();
            aCtx.dispatch();
        }
    };
    Thread t = new Thread(runnable);
    t.start();
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

But now even after I close the connection from client side. The server side code continues to run.

Server keeps printing

Request Received
Error state of the stream: true

indefinitely.

John Eipe
  • 10,922
  • 24
  • 72
  • 114
  • Are you using an `AsyncContext` to get your response and its writer? If not, the connection will be closed after the flush and that triggers the `error` event. – Gergely Kőrössy Aug 29 '15 at 18:57
  • Wow. So it's a must that we need to go for AsyncContext when working with SSEs? – John Eipe Aug 29 '15 at 19:02
  • does the first call to `writer.write("data:blah");` not require the line endings also? viz: `writer.write("data:blah\n\n");` – Professor Abronsius Aug 29 '15 at 19:06
  • @RamRaider Not sure about that. I think we need to append "\n" if it's a continuation but even without the "\n" seems to work for me. – John Eipe Aug 29 '15 at 19:11
  • @John You can use it without that but it will close the connection and the client-side code will reconnect (*and throw a nice `error` before that*). I'd suggest using the AsyncContext. See [this article](https://weblogs.java.net/blog/swchan2/archive/2014/05/21/server-sent-events-async-servlet-example) for more details. – Gergely Kőrössy Aug 29 '15 at 19:13
  • that link mentions a class called, `ManagedExecutorService` which is not available in tomcat – John Eipe Aug 29 '15 at 19:27
  • @GergelyKőrössy Please see my update – John Eipe Aug 29 '15 at 20:02
  • I see. The problem is that the AC needs a listener to listen for the connection state changes. Refer to [this answer](http://stackoverflow.com/a/17304254) for the solution you're looking for. – Gergely Kőrössy Aug 29 '15 at 20:44
  • @GergelyKőrössy Even if I'm sending just one request to the servlet at a time. Would I need the queue and the listeners given in that example? – John Eipe Sep 02 '15 at 07:47

0 Answers0