I've been watching Workers with interest basically since the beginning. Now they just need to bring WebSockets support out of beta. Or is the long-term plan to replace raw WebSockets servers with something higher-level like the new Cloudflare Queues?
Hmm, I believe WebSocket support came out of beta at the same time as Durable Objects, about a year ago. It's entirely possible we forgot to update a doc, though.
We do have some plans around making WebSockets more efficient by allowing the application to shut down while keeping idle WebSockets open, and start back up on-demand when a message arrives.
> We do have some plans around making WebSockets more efficient by allowing the application to shut down while keeping idle WebSockets open, and start back up on-demand when a message arrives.
Please make noise when that rolls out! I was literally wishing for that yesterday.
I want to use Cloudflare Workers to quickly connect p2p WebRTC clients, but when a new peer joins there needs to be open WebSockets to send connection-setup messages to each peer in the room. But with how that works / is billed today it really doesn’t make sense to have a bunch of idling WebSockets.
An alternative is having each client poll the worker continuously to check for new messages, but that introduces a bunch of latency during the WebRTC connection negotiation process.
Instead of adding a non-standard API to opt-out of existing networking functionality, it would be great to see a lower-level networking primitive to unlock these kinds of use cases. I wrote more (with a proof-of-concept) here: https://readable.writable.stream
> A WebSocket being connected to the Durable Object counts as the Object being active.
> If 100 Durable Objects each had 100 WebSocket connections established to each of them which sent approximately one message a minute for a month, the estimated cost in a month would be, if the messages overlapped so that the Objects were actually active for half the month:
I remember looking at that page before and finding these two lines confusing. Based on the first line, it seems that the objects would be considered active for the entire month, whereas the second one raises the possibility that a websocket can be connected to a durable object without it being considered active.
Does the WebSockets protocol now have some kind of built-in keepalive/ping functionality? Something like that is practically necessary for any long-running idle connection on top of TCP. Without built-in keepalive, the application would have to stay running just to handle pings, right?
WebSockets has a protocol-level ping/pong interaction. If one wrote a WebSocket proxy, one could respond to pings on that level, without proxying them to a backend.
While the WebSocket protocol indeed has built-in ping/pong, it's somewhat difficult to rely upon. Web browsers do not provide any API to send pings from the client side. As a result a lot of applications end up implementing application-level pings.
In order to support efficient WebSocket idling, we probably need to have some ability to respond to application-level pings without actually executing JavaScript. TBH I'm not exactly sure how this will work yet.
You could make an incoming WebSocket message behave much like an incoming HTTP request: The DO worker starts running, reads the message, runs any `event.waitUntil` work to completion, and goes to sleep. Let your runtime unload DO workers while holding on to their WebSocket connections.
That would mean maintaining "chatroom" state in memory wouldn't be enough, the DO worker would have to always write it to the durable store, to be safe to unload.
You'd have some sort of a "WebSocket connection ID" that could be used as key for storing state, and when the next message comes in, the worker would use that key to fetch state.
EDIT: And the ability to "rejuvenate" other WebSocket connections from their IDs, so you can e.g. resend a chat room message to all subscribers.