braid-org / braid-spec

Working area for Braid extensions to HTTP
https://braid.org
233 stars 16 forks source link

Heartbeat messages to prevent timeouts #104

Closed josephg closed 1 year ago

josephg commented 3 years ago

Some browsers (Firefox) will automatically close HTTP connections which have no data sent on them after 1 minute.

It feels a little messy, but we should specify a heartbeat message that can be sent from the server to the client during subscriptions, that the client can safely ignore.

(This would also solve a problem I’m running into with Actix-web (rust library) that seems to have no way to find out when a tcp client disconnects except by trying - and failing - to send some bytes).

josephg commented 3 years ago

I have two different proposals for this:

  1. In between updates in a subscription, the client will ignore any arbitrary number of newline (\n) characters. These newlines may be inserted periodically by the server to keep a connection alive.
  2. Allow "empty" update messages. Eg Heart: beat\n\n between real updates

My preference is (1), though I'm happy to be convinced if anyone has another idea. Otherwise I'll write up a PR.

canadaduane commented 3 years ago

Both options seem reasonable. I also prefer (1).

josephg commented 3 years ago

Me too. I've made this change to braid-protocol to send \n newlines as heartbeat messages, and the client ignores any newlines between updates.

mitar commented 2 years ago

Shouldn't heartbeats be done at a transport level and not at braid level? E.g., if subscriptions are done using SSE, then you can use some hearbeat event type. If you use Websockets, then you can use built-in heartbeats.

toomim commented 2 years ago

Shouldn't heartbeats be done at a transport level and not at braid level?

To clarify, Braid defines protocols over different transports (e.g. HTTP and WebSocket), and yes, the encoding of a heartbeat will be different on each one. In this issue we've been discussing how to encode heartbeats in the Braid-HTTP version.

If you use Websockets, then you can use built-in heartbeats.

Good call! I hadn't realized it until you brought it up, but WebSockets do have a built-in ping/pong frame type: https://stackoverflow.com/a/46112000

This isn't exposed in the Javascript APIs for web browsers, but clients will respond to a ping with a pong if the server initiates the ping.

mitar commented 2 years ago

WebSockets built-in ping might be a problem if we care that the JavaScript client knows if the connection is still up or not.

josephg commented 2 years ago

The connection should get closed automatically by the browser when the server goes down or there’s a timeout. I guess we could speed up that timeout if we send our own ping messages. We could add a no-op update message I suppose. I’m not sure how much this matters in practice.

toomim commented 1 year ago

This has been implemented in https://github.com/braid-org/braid-spec/commit/9651ad06537d6d65c9eb40bb2c4e44ff1c2719c2. Closing.