Search code examples
csocketsserver-sent-events

Sending Server-Sent-Events through a socket in C


I have a C-application that produces data I want to push to a website using server-sent-events.

I implemented a basic web server in C that sends the Http-Header after receiving the Http request and then the Data in 1 sec intervals through a socket.

I registered my socket as Event-Source and I'm transmitting a correct HTTP-Header(according to Firebug), but for some reason the eventListener is not called.

var source = new EventSource('http://192.168.2.113:10001/'); 

source.addEventListener('message', function(e) {
/* */
}, false); 

I tried sending the events from a php application and it worked without any problems, so guess the problem is not on the javascript side.

When I just open http://192.168.2.113:10001/ in my browser, the data strings I'm sending in 1 sec intervals are displayed.

I only found sse implementations using php or cgi, which I don't want to use.

My response header:

HTTP/1.1 200 OK\n
Date: Fri, 05 Jul 2013 15:05:15 GMT\n
Cache-Control: no-cache\n
Connection: Keep-Alive\n
Transfer-Encoding: chunked\n
Content-Type: text/event-stream\n
\n

The Event Data:

data: Testdata...\n\n

Solution

  • In chunked encoding, each chunk of data is preceded by a line describing the size of the chunk. You do not show that you are providing this size, so your event data does not follow the chunked encoding format.

    The length is specified in hexadecimal, so in your case, the 18 bytes of data would be encoded as 12 in hexadecimal. When there are no more chunks (that is, the response is complete), then a 0 sized chunk is sent.

    Many clients will accept a plain \n as a proper data unit terminator, but the HTTP RFC specifies that \r\n be used. So, each \n in your header should be changed to \r\n. and your chunks should look like:

    12\r\ndata: Testdata...\n\r\n
    

    The general rule for HTTP applications is: Be liberal about what you accept, be conservative about what you send. This rule means that you should write your application to tolerate loose interpretations of the specification, but deliver data that follows the specification strictly.