Search code examples
javascriptc#httplistenereventsource

EventSource; server-sent events


I am trying to handle EvenSource sent from browser to my C# WebServer.

When I get the HTTP request (Get /event/api/endpoint) .. I reply with: - 200 OK and with - Content-Type: text/event-stream - body: data: null

The console successfully logs the info. On the server I keep the connection opened and response stream open as well. It seems that my server does not send subsequent events over the already opened TCP Response.Outputstream.

The problem that the browser (Chrome) sends new Event as if the connection was closed, but it is not.

Client Code:

<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <title>SSE Test</title>
</head>
<body style="background: #fff;">
    <div id="infoPane">
    </div>
</body>
    <script>
    (function() {
        var infoPane = document.getElementById('infoPane');
        var report = function(msg) {
            var info = document.createElement('p'); 
            info.textContent = msg;
            infoPane.appendChild(info);
        };

        var source = 'http://localhost:8011/SSE/now';
        var loader = new EventSource(source);
        loader.onmessage = function (event) {
            report(event.data);
        };
    }());
    </script>
</html>

Server Code:

var listener = new HttpListener();
listener.Prefixes.Add("http://+:8011/SSE/");
listener.Start();
Task.Run(() =>
{
    while (true)
    {
        var ctx = listener.GetContext();
        Task.Run(() =>
        {
            var response = ctx.Response;
            response.StatusCode = (int)HttpStatusCode.OK;
            response.ContentType = "text/event-stream";
            response.ContentEncoding = Encoding.UTF8;
            try
            {
                while (true)
                {
                    var msg = string.Format("data: it is now {0} Zulu\n\n", DateTime.UtcNow);
                    var bytes = Encoding.UTF8.GetBytes(msg);
                    response.OutputStream.Write(bytes, 0, bytes.Length);
                    response.OutputStream.Flush();
                    System.Threading.Thread.Sleep(1000);
                }
            }
            catch (HttpListenerException)
            {
            }
        });
    }
});

Solution

  • Fixed it as well.

    This is limitation from MSFT HttpListener .. I had to build my own C# HTTP and HTTPS webserver from scratch on top of TCPClient .. that's for sure better than MSFT implementation hundred folds!