DjangoCon Europe 2019: Reduce, Reuse, Recycle - Persisting WebSocket connections with SharedWorkers

Writeup of the DjangoCon Europe 2019 talk »Reduce, Reuse, Recycle - Persisting WebSocket connections with SharedWorkers« by Aaron Bassett

Aaron Bassett: Aaron Bassett has lived in Ireland, Scotland, and is currently wandering around central and eastern Europe. He is a recovering senior software engineer turned award-winning Developer Advocate at Nexmo where he leads their content creation.

Websockets

What are websockets? In the dark ages we had to use iframes if we wanted to update part of a page – the only previous alternative was to reload the page. Or you could use Transfer-Encoding: chunked, which led the browser to accept content until the server told it to stop, which was used mostly to push script content. Next up (ignoring comet), we had Ajax requests, which you could use to send out asynchronous requests, and establish polling.

This is a hack. It's brittle, it's hacked on instead of designed in, both on the server side and the client side. It forces you to re-send all the headers (which can include larger cookie headers). This is a problem once you have several thousands of users! Both for your server, but also for users with limited bandwidth. Also, this hack isn't bidirectional, so the server could not just decide to push data.

Interfacing

On the client side, we have onopen, onmessage, and onclose functions, on new WebSocket(url) objects.

Using Channels, we're talking about Consumers (instead of Views) with an async def connect(self), which handles all incoming connections, and a similar disconnect handler.

Shared WebWorkers

Having a lot of users connect to you via many tabs each is expensive. Shared WebWorkers help with that – they bundle connections coming from the same browser and going to the same origin. They also have onconnect methods, and are also bidirectional – meaning you can communicate from shared worker to page, and back. Basically you're writing your own little bundler/multiplexer/proxy in ~20 lines.

Please note that Shared WebWorkers are browser-local, not host-local. Shared WebWorkers are only available in Firefox and Chrome and Opera, plus Blackberry browser. Safari removed it, and IE/Edge never started. Happily, we don't have to change any server-side code, so support for older browser is not an issue.