How does Server-Sent-Events work

Change this line

writer.write("data: "+ i +"\n\n");

to

writer.write("data: "+ i +"\r\n");

BTW, your code will have a serious performance issue because it will hold a thread until all events are sent.Please use Asynchronous processing API instead. e.g.

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    AsyncContext actx = req.startAsync();
    actx.setTimeout(30*1000);
    //save actx and use it when we need sent data to the client.
}

Then we can use AsyncContext later

//write some data to client when a certain event happens
actx.getResponse().getWriter().write("data: " + mydata + "\r\n");
actx.getResponse().getWriter().flush();

if all events sent we can close it

actx.complete();

UPDATE 1:

We need close the event source at browser if we do not want browser reconnect the server again when server completes the response.

eventSource.close();

Another method maybe helps, viz. we set a quite large retry time but I have not tried it, e.g.

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    AsyncContext actx = req.startAsync();
    actx.getResponse().getWriter().write("retry: 36000000000\r\n"); // 10000 hours!
    actx.getResponse().getWriter().flush();
    //save actx and use it when we need sent data to the client.
}

UPDATE 2:

I think Websocket maybe is better for your case.

UPDATE 3: (answer the questions)

  1. What is actually happening on the server? In normal scenarios, tomcat creates a thread to handle every request. What is happening now?

If use NIO connector which is default in Tomcat 8.0.X, within the whole processing cycle HTTP I/O about a request won't hold a thread. If use BIO a thread will be hold until the whole processing cycle completes. All threads are from a thread pool, tomcat won't create a thread for each request.

  1. What is the correct way to ensure that the event stream is sent only once to the same connection/browser session?

Do eventSource.close() at browser side is the best choice.

  1. What is the correct way to ensure that the event stream is closed and no resource overhead incurs on the server?

Do not forget to invoke AsyncContext.complete() at server side.

  1. How to differentiate between GET and POST requests. Why did it choose GET?

The EventSource API in a browser only supports GET requests but at the server side there 's no such restriction. SSE is mainly used to receive events data from server. If a event happens the browser can receive it in time and no need to create a new request to poll it. If you need full-duplex communication try WebSocket instread of SSE.

  1. Is it too early to use SSE on Tomcat? Any performance issues?

There should be no performance issues if we use NIO connector & Asynchronous processing API. I don't know whether Tomcat NIO connector is mature or not but something will never be known unless we try it.


I highly recommend first to read Stream Updates with Server-Sent Events to get a good general understanding of the technology. Then follow Server-Sent Events with Async Servlet By Example to see how SSE can be used specifically with the Servlet technology.