10

I'm trying to add an endpoint to an existing application that sends Server Sent Events. There often may be no event for ~5 minutes. I'm hoping to configure that endpoint to not cut off my server even when the response has not been completed in ~1min, but all other endpoints to timeout if the server fails to respond.

Is there an easy way to support server sent events in HAProxy?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Josh Wilson
  • 3,585
  • 7
  • 32
  • 53

1 Answers1

11

Here is my suggestion for HAProxy and SSE: you have plenty of custom timeout options in HAProxy, and there is 2 interesting options for you.

The timeout tunnel specifies timeout for tunnel connection - used for Websockets, SSE or CONNECT. Bypass both server and client timeout.

The timeout client handles the situation where a client looses their connection (network loss, disappear before the ACK of ending session, etc...)

In your haproxy.cfg, this is what you should do, first in your defaults section :

# Set the max time to wait for a connection attempt to a server to succeed
timeout connect 30s
# Set the max allowed time to wait for a complete HTTP request
timeout client  50s
# Set the maximum inactivity time on the server side
timeout server  50s

Nothing special until there.

Now, still in the defaults section :

# handle the situation where a client suddenly disappears from the net
timeout client-fin 30s

Next, jump to your backend definition and add this:

timeout tunnel 10h

I suggest a high value, 10 hours seems ok.

You should also avoid using the default http-keep-alive option, SSE does not use it. Instead, use http-server-close.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Guillaume
  • 126
  • 2
  • 6
  • Tunnel timeout may apply to web sockets, I'm less sure it does apply to SSE... The good practice is probably to send keep-alive events from the server every minute or so, and to have `timeout server` twice this delay. – Claude Brisson Oct 23 '22 at 15:26
  • I installed SSE server (NodeJS) and configured it to work with HAProxy. All works good except one thing: when connection is closed on client (EventSource::close()), packet with data about closing the connection isn't going through HAProxy to SSE server (request.on('close', () => { ... }). Any ideas, why? Tried different combination of http-server-close, option httpclose, option http-keep-alive and timeouts, haproxy v2.5, 2.7. Closing connection is sent to SSE server, if use directly (without haproxy). – dixonpfu May 29 '23 at 10:24