Server-Sent Events

HTTP protocol basically involves request-response ,first a client opens a connection sends a HTTP request to the server ,the server sends the http response and the server closes the connection once the response is fully sent to the client. The initiation always comes from the client . Server-Sent Events (SSE) is a mechanism that allows server to asynchronously push the data from the server to the client once the client-server connection is established by the client. Once the connection is established by the client, it is the server who pushes the data and decides to send it to the client whenever new “chunk” of data is available. When a new data event occurs on the server, the data event is sent by the server to the client.

Now lets try to implement it using servlets using below code


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class SSEServlet
 */
@WebServlet("/SSEServlet")
public class SSEServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * Default constructor.
     */
    public SSEServlet() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
//		response.getWriter().append("Served at: ").append(request.getContextPath());

		System.out.println("Got New Request");

	       //content type must be set to text/event-stream
			response.setContentType("text/event-stream");	

			//encoding must be set to UTF-8
			response.setCharacterEncoding("UTF-8");

			PrintWriter writer = response.getWriter();

			for(int i=1; i<=5; i++) {

				writer.write("data: "+ new Date() +"\n\n");
				System.out.println("Serving Old Request "+new Date());
				writer.flush();
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			writer.close();
			System.out.println("Closing Old Request Connection");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

now create a html file with below code


<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<button onclick="start()">Start</button>

<script type="text/javascript">
    function start() {
        var eventSource = new EventSource("SSEServlet");
        eventSource.onmessage = function(event) {
            console.log("data: "+event.data)
            document.getElementById("foo").innerHTML = event.data;
        };
    }
</script>
<p id="foo"></p>

</body>
</html>

Now test it using http://localhost:8080/SSEServletExample/servlet.html and you will get output as

Sun Apr 30 19:53:36 IST 2017

where second keeps on changing and on after every 5 seconds the old connection is closed and new connection is created which can be seen is logs below

Got New Request
Serving Old Request Sun Apr 30 19:53:36 IST 2017
Serving Old Request Sun Apr 30 19:53:37 IST 2017
Serving Old Request Sun Apr 30 19:53:38 IST 2017
Serving Old Request Sun Apr 30 19:53:39 IST 2017
Serving Old Request Sun Apr 30 19:53:40 IST 2017
Closing Old Request Connection
Got New Request
Serving Old Request Sun Apr 30 19:53:44 IST 2017
Serving Old Request Sun Apr 30 19:53:45 IST 2017
Serving Old Request Sun Apr 30 19:53:46 IST 2017
Serving Old Request Sun Apr 30 19:53:47 IST 2017
Serving Old Request Sun Apr 30 19:53:49 IST 2017
Closing Old Request Connection
Got New Request
Serving Old Request Sun Apr 30 19:53:53 IST 2017
Serving Old Request Sun Apr 30 19:53:54 IST 2017
Serving Old Request Sun Apr 30 19:53:55 IST 2017
Serving Old Request Sun Apr 30 19:53:56 IST 2017
Serving Old Request Sun Apr 30 19:53:57 IST 2017
Closing Old Request Connection

Use eventSource.close(); if you dont want the client(browser) to reconnect once the response from the server is completed.but Websockets are better for this case.

Posted in Java, WebDevelpment | Leave a comment