Question

One of the fallback of signalR is SSE - server sent events. which all it does is sending a message via this structure :

Message\n\n

so in the server side :

Response.ContentType = "text/event-stream";

while (startDate.AddMinutes(1) > DateTime.Now)
{
    Response.Write(string.Format("data: {0}\n\n", DateTime.Now.ToString()));
    Response.Flush();

    System.Threading.Thread.Sleep(1000);
}

great.

but not so great.

I could easily use JS command with data ( like jsonp does aka : padding with callback object analogy) for example : _ cb(myMessage)

And in the client side - deal with it as the same.( even with more welcome mime type like application/javascript)

I'm probably missing something here.

  • What is the advantage of SSE ?
Was it helpful?

Solution

The biggest advantage of Server-sent events (SSE) over JSONP/long-polling is that you can read each chunk of an SSE response as soon as the chunk is received without the response ever needing to be completed.

You can use chunked responses to send back a JSONP payload, but the <script src="... tag responsible for loading the JSONP payload will not execute the JavaScript until the entire response is complete. In practice, this means that you have to complete the response whenever you send a message to the client using JSONP so the client can read the message immediately.

This in turn means that the client has to make a new JSONP request (i.e. add a new script tag to the document) for each message it receives. This is why JSONP is considered a long-polling transport.

Now, as you mentioned in one of your comments, you can use an iframe instead of a script tag to load your JavaScript payload. If you do this, you can send back chunked responses and have the JavaScript execute before the response is completed just like with SSE.

In fact, this hidden iframe technique this is exactly what SignalR uses in for its forever-frame transport. Unfortunately there are a couple downsides to this technique that cause SignalR to prefer SSE on browsers that support it:

  1. The hidden iframe technique requires a relatively hefty prelude* since you are actually sending back an HTML document instead of pure JavaScript.

  2. Each message needs to be wrapped in its own script block in addition to a function call. (e.g. <script>c({"message": "myMessage"})</script>). With SSE you only need to send data: {"message": "myMessage"}\n\n which is slightly more efficient.

  3. Lastly, and perhaps most importantly, the memory consumed by the hidden iframe is never cleaned up until it is removed from the DOM. This means that if you don't want unbounded memory growth, you have to periodically create a new iframe and remove the old one. The EventSource object used by the SSE transport can remain open indefinitely without leaking memory.

* SignalR's forever-frame prelude:

<!DOCTYPE html><html><head><title>SignalR Forever Frame Transport Stream</title>
<script>
    var $ = window.parent.jQuery,
        ff = $ ? $.signalR.transports.foreverFrame : null,
        c =  ff ? ff.getConnection('1') : null,
        r = ff ? ff.receive : function() {};
        ff ? ff.started(c) : '';</script></head><body>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top