@KentonVarda when will we be able to read/write websockets (within workers), and not just proxy them? We also need UDP support from the workers. With UDP support I can take advantage of sendmmsg/recvmmsg or specialized kernel bypass nics within my backend.
There are two tricky questions to answer with WebSocket support:
What’s the API? Service Workers in the browser today actually can’t intercept WebSockets, and so there’s no standard API defined for doing so. We’ll need to make up something new, hopefully with some chance that it will be accepted into the standard later.
How should WebSockets affect the per-request CPU time limit? Is a whole WebSocket just one request, with the same CPU limit as any other? Or do we treat it as multiple requests (and bill accordingly)?
I can’t make any firm promises, but I would expect WebSocket termination support to show up in the next month or two, but probably treated as a single request with a single CPU time limit. From there we’ll have to see in practice whether changes to the time limits are needed.
Wouldn’t it be better to leave websocket open and bill max(bandwidth, time) per minute?
@jdavis Workers are billed on number of “requests”, not on bandwidth nor CPU time. I don’t think we’d want to add CPU or bandwidth metering that applies only to WebSocket. So we need to turn WebSockets into “requests” somehow…
Wasted effort, probably best to just forget websockets in that case. Maybe push this effort into TCP anything?
I think we can find a reasonable way to count WebSockets as requests for billing purposes.
So we’re talking about being able to keep websockets open for an extended period of time? If not, what’s the point?
On another note, when is CloudFlare going to purchase ZeroTier and use it’s kernel-bypass expertise to make ZT run screaming fast? In addition, making ZT run within websocket framing on 443 would also be quite disruptive.
Hello @KentonVarda ,
has there been done any progress internally on the Websockets? I would be curious whether we can expect it soon or rather you found complications and decided to postpone it for time being.
Many thanks for reply!
@janusz We have a lot on our plate and unfortunately this is not our top priority, but in the time between other things I have managed to create a prototype implementation allowing a Worker to terminate WebSockets as a client or a server. There are still problems with this prototype:
- In my prototype, an outgoing WebSocket can only be used in the context of the FetchEvent that initiated it. You can’t store it to a global variable and use it across multiple incoming requests. This is because subrequests are intrinsically tied to the FetchEvent that created them in our implementation’s concurrency model. For some use cases this is fine, but for others it may be disappointing. It’ll take a fair amount of work to change this, but it can be done.
- There’s still no way to extend the CPU timeout beyond 50ms, as mentioned above. Solving this is more of a product question than an engineering question, so requires some discussion within the organization.
- I’ve only implemented the bare minimum components of the API. The standard defines a wider API surface that needs to be filled out.
- I have had to extend the Fetch, Service Workers, and WebSocket APIs in non-standard ways, and would like to run my changes past WHATWG before we commit to anything.
Unfortunately since we have a lot of other high-priority things competing for our time, it’s hard for me to say how long it will take to finish this up. It seems like at least a few months away.
I’d be interested to know which of the above constraints would be problems for your use case. If none of them are, then maybe we can have something working for you relatively sooner.
My initial idea would be to treat websocket termination more as a high level cloudflare service similar to how currently http2 and ssl services are handled and expose just message events to worker functions, were the message events have additional matadata properties to know everything relevant about the connection. This way it could be easy to bill 3 or 4 websocket messages as one request and the concurrency and timout characteristics of workers would play nicely.