Spring MVC - HTTP Streaming With Server-Sent Events

[Updated: Jan 4, 2017, Created: Jan 3, 2017]

SSE (Server-sent Events) is a W3C standard. It is a just another variation of the "HTTP Streaming" technique we saw in the last tutorial, except that, events pushed from the server are formatted according to the W3C Server-Sent Events specification.

Spring class SseEmitter provides support of SSE. It is a subclass of ResponseBodyEmitter. Let's see a quick example how to use this class:


The controller

@Controller
public class MyWebController {

    @RequestMapping("/sseTest")
    public ResponseBodyEmitter handleRequest () {

        final SseEmitter emitter = new SseEmitter();
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(() -> {
            for (int i = 0; i < 500; i++) {
                try {
                    emitter.send(LocalTime.now().toString() , MediaType.TEXT_PLAIN);

                    Thread.sleep(200);
                } catch (Exception e) {
                    e.printStackTrace();
                    emitter.completeWithError(e);
                    return;
                }
            }
            emitter.complete();
        });

        return emitter;
    }
}

Spring Boot main class

@SpringBootApplication
public class SseExample {
    public static void main (String[] args) {
        SpringApplication.run(SseExample.class, args);
    }
}

Output

Using SseEmitter with JavaScript

SSE specification defines client side scripting handling as well. The real advantage of using SseEmitter can be seen when used with JavaScript.

In the following example we are going to add a static web page to initiate the SSE request from javascript.

Regarding where to place static pages, by default Spring Boot serves static contents from a directory: /static or /public or /resources or /META-INF/resources in the classpath.

Let's add index.html under src/main/resources/public/

<!DOCTYPE html>
<html>
<body>

<h1>Sse client</h1>
<a href="javascript:void" onclick="sendRequest()">Send Request</a>
<div id="sseDiv"></div>

<script>
function sendRequest(){
if(typeof(EventSource) !== "undefined") {
    var source = new EventSource("/sseTest");
    source.onmessage = function(event) {
        document.getElementById("sseDiv").innerHTML += event.data + " - ";
    };
} else {
    document.getElementById("sseDiv").innerHTML =
                     "Your browser does not support server-sent events.";
}
}
</script>

</body>
</html>

There's no change with our controller from the previous example.

Output

On Clicking 'Send Request':



Note that, just like ResponseBodyEmitter, SseEmitter also uses an HttpMessageConverter for object to HTTP message conversion. Also it can be wrapped in ResponseEntity. Please check out related examples: MyWebController2 and MyWebController3, in the project browser below




Example Project

Dependencies and Technologies Used :

  • Spring Boot Web Starter 1.4.2.RELEASE: Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container.
    Corresponding Spring version: 4.3.4.RELEASE
  • JDK 1.8
  • Maven 3.3.9

Sse Emitter Examples Select All Download
  • spring-mvc-sse-emitter
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • resources
          • public

See Also