AnsweredAssumed Answered

How to detect a closed socket on the MQX httpsrv

Question asked by Luiz Fernando Schrickte on Jul 11, 2014
Latest reply on Jul 14, 2014 by Karel Mozny

Hi folks,

 

I'm trying to use the HTML5 Server-Sent Events approach for event streams (single direction) for a specific application I have here.

 

For those who are not familiar with the HTML5 Server-Sent Event approach (like me two days ago), I recommend this reading: HTML5 Server-Sent Events

 

Basically a client access a HTML page in the server which triggers a javascript specific code that keeps accepting incoming data from the server. The HTTP headers are passed by the server just in the first response, with Content-Type set to text/event-stream. After that all data is sent almost "as-is", with no overhead, except for some format conventions (data: nonono\n\n)

 

MQX httpsrv doesn't have native support for this kind of communication, but I've figured out a way to make things work:

 

1. I'm using the MQX httpsrv CGI support

2. Every time the cgi function is called, I detach a task for its execution (stack > 0 in the cgi_tbl) and the cgi handler enters in an infinite loop, which calls the HTTPSRV_cgi_write(&response); function every time an event happens in my application (using a sync mechanism)

3. As the internal httpsrv_write function bufferizes the data on the session buffer until it is full, this didn't work in the beginning, as the data were only being sent when the buffer get full indeed. The workaround for this is to call the (private) httpsrv_ses_flush((void *)param->ses_handle); after the HTTPSRV_cgi_write function, so the server forces a flush.

 

Well, things are working nice, but I've just one small issue! I can't detect when the client is not connected to the server anymore!

 

When I close the client, I can see in wireshark that the connection is closed - no more data is exchanged, however the HTTPSRV_cgi_write and the httpsrv_ses_flush functions in the server continue to return success values, so I've no way to find out that the socket is no longer active!

 

I've an ugly solution, which is to simply 'break' the while loop in the CGI script periodically, finishing the CGI handler execution, so the client must reconnect to the server (it does it automatically, another feature of the HTTP SSE approach) and, if the client is no longer available, nobody gets the events and everything is fine. However I wish there was a way to detect that the connection was lost right after the "FIN, FIN,ACK" packets were exchanged and the connection was closed. Is there a way to do this? I've already noted that the send function is not returning error, even after the connection is lost... so how can I find out that the tcp connection is already closed?

 

Maybe support the HTTP Server-Sent Events approach in the httpsrv default implementation in the future would be a nice idea! I think that with little effort it is possible add this support (a flag in the CGI Write call to flush data would be a beginning + http text/event-stream type support in the default content types list).

 

Thank you very much!

Luiz Fernando

Outcomes