WebSocket and Durable Object

Problem : When client A publishes a message, client B receives it immediately. But clients C, D, E never receive the message. Clients C, D, E or Workers W3, W4 have to realize a pull operation to get the message. At local and global scale, pulling nullifies WebSocket benefits.

Proposal 1 : DO implements WebSocket.
OnClientConnect, Worker connects to the given room DO (if not already connected). On put, DO notifies the connected Workers (except the one who put). OnClientDisconnect, If no other client is interested, Worker disconnects from the given room DO. If DO disconnects Worker, if there are still clients interested, apply OnClientConnect, otherwise apply OnClientDisconnect.

Proposal 2 : DO implements PubSub. Subscriptions are temporary to avoid zombie subscribers. DO notifies subscribers when their subscription is removed.
OnClientConnect, Worker subscribes to the given room DO (if not already subscribed). On put, DO notifies the subscribed Workers (except the one who put). OnClientDisconnect, If no other client is interested, Worker unsubscribes from the given room DO. If DO unsubscribes Worker, if there are still clients interested, apply OnClientConnect, otherwise apply OnClientDisconnect.

Both proposals enable worldwide, real time, 2-ways, client to client communications.

Hi @denis.truffaut,

Durable Objects already support WebSockets. This is how our chat demo works – the WebSocket corrections from the client are proxied through the Workers to the Durable Object for the chat room, where it can then multiplex messages from one client to all the others. See the code here:

3 Likes

Oh ! I see that now.

Line 190
Line 228
Line 254

Thanks for pointing this.
It is a lot clearer now !
:+1: :100:

Update on the schema:

If I understand correctly, clients need to have -somehow- knowledge of the roomId before they connect :

  • Option 1 (Default room) : We know the unique roomId (previously generated). The chat session starts with 10 billion users. Not sure it scales well. Is there a hard limit ?

  • Option 2 (Type roomId in an input) : User A make a call to a Worker. It generates a unique roomId. Send back. User A communicates the roomId to user B through an external tool (SMS, email…). Users A & B type the code. The chat session starts.

  • Option 3 (Autoconnect - Users with id only) : A & B generate the same hash based on A & B ids (they know each other ids). A & B make a call to a Worker. Workers generate a unique roomId based on the hash. Generated roomId is the same for A & B, because env.rooms.idFromName is consistant. Send back. Users A & B can connect to the room. The chat session starts.

Option 3 works best with logged users, but for anonymous users we could assign them - client-side - a temporary id prefixed by ‘anonymous’.

If we create for each user a mailbox (a personal DurableObject attached to the user), each user from the conversation can furthermore communicate the roomId to additional users through their mailboxes (roomdId is known once their are friends) thus invite them to the conversation. Thanks to websockets, invitation is received in real time.

And it is absolutely possible to sugar this with End to End encryption if needed.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.