Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bi-Directional Keep-Alive Initiation #8

Closed
1 task done
amydevs opened this issue Sep 11, 2023 · 6 comments
Closed
1 task done

Bi-Directional Keep-Alive Initiation #8

amydevs opened this issue Sep 11, 2023 · 6 comments
Assignees
Labels
development Standard development r&d:polykey:core activity 4 End to End Networking behind Consumer NAT Devices r&d:polykey:supporting activity Supporting core activity

Comments

@amydevs
Copy link
Contributor

amydevs commented Sep 11, 2023

Specification

On the WebSocketConnection there are two variables that govern the Keep-Alive:

  • keepAliveIntervalTime - The time interval between which pings are sent (note that this is also the amount of time that needs to have elapsed for the first ping to be sent by a client or server after establishing a WebSocketConnection)
  • keepAliveTimeoutTime - The maximum time interval between receiving pings (or messages), otherwise timeout

The keep-alive will need to be able to be initiated both on the client-side or the server-side.

How this will be implemented is that:

  • client and server both start pinging initially
  • if the client receives a ping, stop pinging
  • if the server receives a ping, keep pinging
  • if the server receives two pings, stop pinging
  • if either a client or a server receives a ping or data, their next scheduled ping is rescheduled to be now + keepAliveIntervalTime
  • both the server and client must pong on receiving a ping

This will mean that both the client and the server can establish keep-alive responsibility.

It is important to note that on a browser window.WebSocket instance, pings and pongs are abstracted away. The browser will automatically respond to any pings from a server with a pong, but are assumed to never send any pings. The reason that the server will only stop pinging after receiving to pings is so that in case a browser implementation unreliably pings, there is less chance for the connection to timeout as the server requires a second ping for confirmation that the client takes the responsibility of pinging.

Client Initiated Keep-Alive:

Untitled-2023-06-09-1740 excalidraw(8)

In this case, both the client and the server are able to send pings. This would occur in the circumstance where both the server and client are in a node context. The client schedules a ping to be sent on the first second, but the server schedules a ping to be on 2 seconds. The server receives a ping before it's own ping can be sent. So at the 1st second, the server reschedules its ping to be sent on the 3rd second. However, the client sends a second ping on the 2nd second and establishes responsibility for Keep-Alive, and the server cancels its scheduled ping.

Server Initiated Keep-Alive:

Untitled-2023-06-09-1740 excalidraw(6)

In this case, either the client is a browser or the keepAliveIntervalTime of the client is longer than that of the server. That means the client receives a ping before their scheduled ping is sent, cancelling it.

if the keepAliveIntervalTime on a client is less than that of the server, the client can eagerly ping twice to establish keepalive responsibility before the server is ever able to ping. This is because the the server's scheduled ping is reset after every ping the server is received, so that the server is never able to send a ping before the client establishes responsibility. This will be the case unless the server immediately starts sending data to the client, as the client's ping will be continuously refreshed, allowing the server to take responsibility for Keep-Alive. This is okay, as responsibility should be based on urgency rather than being deterministic.

Additional context

Tasks

  • 1. Implement
@amydevs amydevs added the development Standard development label Sep 11, 2023
@tegefaulkes
Copy link
Contributor

What if both sides ping on their own interval, but if a side receives a ping it refreshes it's ping delay. That way the one that sends first or has a smaller interval should have priority when pinging. The other side will only ping again if its ping delay wasn't refreshed by receiving a ping.

@amydevs
Copy link
Contributor Author

amydevs commented Sep 11, 2023

What if both sides ping on their own interval, but if a side receives a ping it refreshes it's ping delay. That way the one that sends first or has a smaller interval should have priority when pinging. The other side will only ping again if its ping delay wasn't refreshed by receiving a ping.

That is a good point ty

@CMCDragonkai
Copy link
Member

CMCDragonkai commented Sep 12, 2023

As discussed yesterday the solution should be quite simple here.

Both the interval timer and timeout timer refresh as soon as they receive any data from the peer, whether that is a data, or a ping.

Whenever you get a ping, you send out a pong no matter what.

The ping interval will run and execute even if you're continuously sending data, with no response from the other side.

Then whichever one has the lowest ping interval or sends data first will generally be the one doing the pinging. Both sides may naturally take turns on who is doing the pinging depending on which side becomes more of a sender compared the other side.

This algorithm is co-ordination less and achieves the main goal of the keep alive system - keeping the connection alive.

@CMCDragonkai
Copy link
Member

I believe this is done by #5 now, reopen if not @amydevs.

@amydevs
Copy link
Contributor Author

amydevs commented Sep 26, 2023

I believe this is done by #5 now, reopen if not @amydevs.

The keepalive on staging is still currently on both sides ping regardless, i'll change this asap

@amydevs
Copy link
Contributor Author

amydevs commented Sep 28, 2023

fixed by commit a694f4c

@amydevs amydevs closed this as completed Sep 28, 2023
@CMCDragonkai CMCDragonkai added r&d:polykey:core activity 4 End to End Networking behind Consumer NAT Devices r&d:polykey:supporting activity Supporting core activity labels Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
development Standard development r&d:polykey:core activity 4 End to End Networking behind Consumer NAT Devices r&d:polykey:supporting activity Supporting core activity
Development

No branches or pull requests

3 participants