Skip to content
This repository has been archived by the owner on Aug 7, 2019. It is now read-only.
sbordet edited this page Apr 24, 2012 · 6 revisions

Jetty EventSource Servlet

The Jetty EventSource Servlet is an implementation of HTML5's EventSource Specification, also known as Server-Sent Events, from the Jetty Project.

Dependencies

The Jetty EventSource Servlet is only dependent on the portable Jetty Continuations library. It will therefore work in any servlet 2.5 (or greater) servlet container, and does not require to be run in the Jetty servlet container.

Your web application needs to declare dependencies on the Jetty EventSource Servlet and on the Jetty Continuations. These dependencies needs to be included in the WEB-INF/lib directory of your web application.

Emitting Server-Sent Events

In order to be able to send server-sent events, you need to subclass EventSourceServlet to return an instance of the EventSource interface, by implementing method newEventSource(HttpServletRequest):

public class MyEventSourceServlet extends org.eclipse.jetty.servlets.EventSourceServlet
{
    @Override
    protected EventSource newEventSource(HttpServletRequest request)
    {
        return new MyEventSource();
    }
}

The newEventSource(HttpServletRequest) method will be called every time a client creates a new EventSource JavaScript object (refer to the HTML5's EventSource Specification for further details).

Your application (class MyEventSourceServlet in the example above) must return a different EventSource object each time method newEventSource(HttpServletRequest) is called.

The EventSource implementation returned by your application (class MyEventSource in the example above) is provided with an EventSource.Emitter instance that allows you to send server-sent events to the client:

public class MyEventSource implements org.eclipse.jetty.servlets.EventSource
{
    private Emitter emitter;

    public void onOpen(Emitter emitter) throws IOException
    {
        this.emitter = emitter;
    }

    public void emitEvent(String dataToSend)
    {
        this.emitter.data(dataToSend);
    }

    public void onClose()
    {
    }
}

Your application can call method emitEvent(String) every time it needs to send an event to the client.

Emitter instances are fully thread safe.

Method onOpen(Emitter) is called when the client establishes a connection with the server and successfully negotiates the event source protocol over the connection.

Method onClose() is called when the client closes the connection.

General Configuration

Your EventSourceServlet subclass needs to be configured in your web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <servlet>
        <servlet-name>eventsource</servlet-name>
        <servlet-class>com.acme.MyEventSourceServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>eventsource</servlet-name>
        <url-pattern>/sse</url-pattern>
    </servlet-mapping>

</web-app>

If you are running in a Servlet 3 compliant container (Jetty 8, Tomcat 7, etc.), this is the web.xml configuration that you want to use:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <servlet>
        <servlet-name>eventsource</servlet-name>
        <servlet-class>com.acme.MyEventSourceServlet</servlet-class>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>eventsource</servlet-name>
        <url-pattern>/sse</url-pattern>
    </servlet-mapping>

</web-app>

With this configuration, a JavaScript client can establish the connection using:

var eventSource = new EventSource("http://localhost:8080/mywebapp/sse");
eventSource.onmessage = function(event)
{
    window.console.info("Server-Sent Event: " + event.data);
};

Tomcat 7 Configuration

Tomcat 7 needs to be configured to use the NIO connector instead of the default BIO connector. You have to edit the protocol attribute on the Connector element in your server.xml:

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" />