Mawg
Mawg

Reputation: 40149

Cross browser Server-sent Events, or alternative, including Microsoft browsers

According to Can I use?, the MS IE & Edge browsers do not support Server-sent Events.

Is there a workaround?

Or an fully cross browser alternative which is as simple (which websockets do not seem to be (and, in any case, I prefer to stick to HTTP and not have multiple simultaneous protocols complicating things))?

I want AngularJs clients to be able to subscribe & unsubscribe PHP server pushed JSON data, with multiple clients being able to subscribe to the same data and only a single server action being necessary to push it, preferably without knowing to whom to push it.

Upvotes: 3

Views: 2366

Answers (2)

Mario
Mario

Reputation: 1791

There are a couple of EventSource polyfills for MSIE:

https://github.com/remy/polyfills/blob/master/EventSource.js

https://github.com/amvtek/EventSource

One of them (don't remember which) displays an annoying Alert message periodically, so you will probably have to edit the code and remove them.

You can find here an example of usage:

https://github.com/mariomac/jeasse/blob/master/examples/chat-servlet3/src/main/resources/static/index.html

Upvotes: 2

Darren Cook
Darren Cook

Reputation: 28928

Microsoft's stubbornness over SSE is quite incredible, especially as implementing it is really just a layer over XMLHttpRequest2, the standard is short, there has been a wonderful O'Reilly book about it out for 3 years, and there are at least two open source implementations to take inspiration from.

Anyway, the recommended technique to get compatibility back to IE8 is to create a hidden iframe, and then keep polling its inner source, and just return anything that is new there:

iframe = document.createElement("iframe");
iframe.setAttribute("style", "display: none;");
iframe.setAttribute("src", "abc_stream.php");
document.body.appendChild(iframe); 

If you only need to support back to IE10, you can use an XMLHttpRequest2 object, and listen to the readyState==3 messages:

xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
    //Read this.responseText from the previous offset onwards
    };
var u = url;   
u += "xhr=1&t=" + (new Date().getTime());
xhr.open("GET", u);

These techniques need only very slight support on the back-end: if a client is connecting with real SSE, you have to set the MIME type as text/event-stream, but if using the xhr hack you have to set it as text/plain. I have it append xhr=1 to the URL, as shown above (and the timestamp to stop it being cached).

The xhr technique will work on all browsers where SSE works, if you did want to go for a single solution. It's one downside is that the full data being sent is building up in memory. (My suggestion is to auto-reconnect whenever the responseText is over 64KB, or something like that.)

Upvotes: 5

Related Questions