Daniel
Daniel

Reputation: 1676

Jersey Server-Sent Events not working with Firefox

Jersey 2.1.4, Java 8, Tomcat 8, Firefox 38.0.1

Server:

@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput listenToBroadcast() {
    final EventOutput eventOutput = new EventOutput();
    this.broadcaster.add(eventOutput);
    return eventOutput;
}

Client:

var source = new EventSource('broadcast');
source.addEventListener('event', function(event) {
    alert('event');
}, false);
source.onopen = function() {
    alert('connection open');
};

Using Firefox, the connection open alert does not show up on page load. Firefox shows the following error in the console: Firefox can't establish a connection to the server at http://localhost:8080/broadcast. The onopen function DOES get called when the first event comes in. And in that case, only the onopen function is called, and not the event listener.

Chrome is working properly. Also, this demo is working with Firefox properly.

On page load, and before the server sends an event, The Network tab in Firefox shows that it received OK 200 for the /broadcast SSE endpoint, but no headers are present. Jersey log shows the following for the connection establishment:

o.glassfish.jersey.filter.LoggingFilter  : 11 * Server has received a request on thread http-nio-8080-exec-3
11 > GET http://localhost:8080/broadcast
11 > accept: text/event-stream
11 > accept-encoding: gzip, deflate
11 > accept-language: en-US,en;q=0.5
11 > cache-control: no-cache
11 > connection: keep-alive
11 > host: localhost:8080
11 > pragma: no-cache
11 > referer: http://localhost:8080/test_sse.html
11 > user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101     Firefox/38.0

11 * Server responded with a response on thread http-nio-8080-exec-3
11 < 200
11 < Content-Type: text/event-stream

Upvotes: 2

Views: 3339

Answers (1)

Daniel
Daniel

Reputation: 1676

My client was waiting on the EventSource.onOpen event after creating the EventSource connection (new EventSource()). Chrome invokes the onOpen callback right after the connection is open, but Firefox would only invoke it when the first event is sent from the server. To work around this, I am sending a comment event right after the server opens up the SSE connection. Firefox gets this event, which is meaningless, and calls the onOpen function. Here is my server-side client subscription code:

@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput listenToBroadcast() {
    final EventOutput eventOutput = new EventOutput();
    this.broadcaster.add(eventOutput);

    // firefox doesn't call the EventSource.onOpen callback when the connection is created, but it requires at least one event to be sent, so a
    // meaningless comment event is used
    OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
    OutboundEvent event = eventBuilder.name("event")
            .comment("")
            .build();
    broadcaster.broadcast(event);
    return eventOutput;
}

However, FF still show an error on the console: The connection to http://localhost:8080/broadcast was interrupted while the page was loading. You can see the error showing up using this demo Probably a known bug

Upvotes: 6

Related Questions