Eventsource/Server-Sent Events Through Nginx

EventSource / Server-Sent Events through Nginx

Your Nginx config is correct, you just miss few lines.

Here is a "magic trio" making EventSource working through Nginx:

proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;

Place them into location section and it should work.

You may also need to add

proxy_buffering off;
proxy_cache off;

That's not an official way of doing it.

I ended up with this by "trial and errors" + "googling" :)

SSE event data gets cut off when using Nginx

The above mentioned configuration actually did work. However, the server I was using contained another nginx configuration that was overriding my configuration. When the configuration parameters specific for SSEs were added to that configuration as well, things started working as expected. So this question was correct all along.

Server sent events stopped work after enabling ssl on proxy

For SSE to work properly, you must make sure nothing is getting cached or buffered: not in your script (e.g. in PHP we have the @ob_flush();@flush() idiom), not at your web server, and not at any intermediate proxies or firewalls.

You say you commented out all the nginx commands to do with buffering, but commenting out means it will use the defaults. E.g. the default for proxy_buffering is on. I would suggest explictly specifying them to make sure all buffering and caching is switched off.

proxy_buffering off;
proxy_buffer_size 0;
proxy_cache off;

I would also consider explicitly setting the timeouts high, rather than commenting them out. The definition of "high" depends on your application. E.g. if it is always sending data every couple of seconds, the defaults will be fine. But if you are using SSE for irregular data, and there might sometimes be half an hour between messages, make sure the timeouts are more than half an hour.

UPDATE: Apparently (see the comments) adding response.addHeader("X-Accel-Buffering", "no"); (i.e. to the server-side process, not to the proxy config) fixes the problem. This makes sense, as that was added specifically for SSE and similar HTTP streaming, see the nginx documentation. It does imply the above Nginx configuration should also work (the OP has reported that it does not). But, on the other hand, using a header to disable buffering on a per-connection basis feels like a better solution anyway.

Server-Sent Events connection timeout on Node.js via Nginx

Answering to myself. Actually solution was not that difficult to find, it just demanded careful look into nginx documentation.

proxy_read_timeout is a directive responsible for that, and by default it's set to 60 seconds. So it can be easily fixed by setting e.g.:

proxy_read_timeout 24h;

Setting 0 won't work, it will actually make all your connections broken, therefore we need to come up with long enough timeout.

After fixing that I approached also the other issue, but this time related to how browsers handle the connection. For some reason after 5 minutes of inactivity browsers silently discard the connection. What's worse neither side is informed that it's discarded, for both it still appears as if connection is online, but data doesn't get through. Fix for that is to send some keep alive ping on interval basis (plain sse comment works great).



Related Topics



Leave a reply



Submit