[ ] Of course! Channels actually stems from about three or four years ago. I’m sure your audience is aware of this, but if they’re not, websockets came onto the scene about five or six years; it was sort of life, “Oh, we need bidirectional communication for the web. HTTP is not good enough.” So a team of developers of the various browser manufacturers - mainly Google, in fact - were sort of developing at this protocol like, “Well, what kind of protocols do we have? How’s it gonna work? How are we gonna encode it? It has to start with HTTP…” I was following at the time this development, like “What is websockets, how is it going along?” and back then I was actually using a Python framework called Eventlet, which is sort of an asynchronous programming framework for Python; they had a websocket library, and the spec was changing pretty much every month at that point, and so I’d put a few patches in to try and keep it with the current with the current spec. They found security holes and found some replay attach thinkgs like that. But I think about three or four years ago it stabilized pretty much, and then I sort of got interested. As the web evolves, we see this trend towards websites being much more of like a heavy application. “Single-page applications” is one of the buzzwords you hear. A websocket is this application, full of logic, it has to communicate with the backend server, and a lot of that is still being done over REST and over HTTP. That’s great, that works really well for a lot of stuff, I appreciate the boringness of that, it’s very well understood, but for some things it just doesn’t work.

An example from my real place of work, Eventbrite - there’s a seat map where you can pick seats from, and the seats gray off in real time as they’re picked; if we did that using HTTP, we’d have to do that long polling, bundle it up on the backend and make sure it’s all done efficient. And we did use to do that as well, but the key thing is websockets give you this really easy, quick, efficient way of sending data backwards and forwards to and from the browser. It’s not standardized, it’s a slightly crazy protocol on the wire, but pretty much it is a datagram-based protocol, you can send and receive packets - that’s pretty much it; it’s all stuff under the scenes. And it got bigger and bigger.

I saw it as like, “Well, obviously as these applications get bigger and more complicated, they obviously will require more and more communication with the backend, and at some point sockets make sense. And then Meteor comes along, and Meteor is a thing I see and go, “Ah!” Everybody is like, “This is a really clever way of doing this.” Meteor is this great idea of like, “We can use sockets to do data binding and send data both directions across the socket.” So Meteor was the spark for me, “We could do that in Django maybe.”

The problem is, of course, for the listeners who aren’t aware, Python is a single-threaded language at its core. We have a threading model, but the threading model is just time-sharing on a single core; there’s no actual multi-threading in there. On top of this, support for what’s called “asynchrony”, as in you can open lots and lots of virtual threads and wait on sockets and do things out of order, only came in in Python 3.5. Django supports Python 2.7 and up, so we have the limitation there - Django has to support all these different versions of Python, and in addition, when I was thinking about this a couple of years ago, async wasn’t even mature yet.

For a little while, Aymeric Augustin, one of the core developers of Django did some work with websockets with Django, and his work was really quite good. A game of life where every cell of the game of life was a websocket which is actually kind of amazing; I really enjoyed that demo. He sort of did that, and he moved on from that, but it was still a really nice proof of concept.

Then about a year and a half, two years ago I sort of… Django Migrations, which had previously been my baby, was done, merged. Some other core developers had very kindly taken up a lot of the mantle of maintaining it - I got a bit burnt out merging in the 1.7 release… I was still helping out occasionally with migrations, but I was thinking “What else is Django missing?” I had spent eight years fixing this big hole in Django that I saw in 2006. What do I do now?

[ ] So I sat down and thought, “Well, in my opinion, and what I am excited about, is websockets. I’m excited about these things in the browser…” You know, I also do game development on the side, sometimes I wonder about games in the browser, like “What’s that look like? We obviously need sockets for that, for proper real-time communication.” So I sat down and started sketching out sort of like a prototypical “How would this API work? How would I want it to work?” and then saying, “Could I do this with Django? Could I do this with Python even?” And it’s difficult; there are solutions out there already, and there always have been for a long time, that rely on a set process running. That process is using an asynchronous framework, be it Twisted, or Tornado, or Async.io or GEvent, or one of the many other ones that Python has. That framework is capable of handling the idea of lots of simultaneous connections, and if you have this framework running a separate process, that can handle websockets and then everything’s good, and it sort of communicates somehow with the main server over some kind of socket, and then you can get sort of socket support, but it’s not properly there.

There are a lot of downsides to this solution. The first thing is that server generally only handles websockets. You can’t just point your server at that server; you have NGINX in front and then you have a path based routing. It’s like, if you see the path /ws, go to the websocket server, otherwise use the main server… It gets a bit tricky.

On top of that, another part of it is HTTP/2. Websockets are not the only thing changing on the web. HTTP/2 is also coming in, and it’s coming in in force; it’s been a slow build, but it’s getting there. HTTP/2 also has a lot of changes in terms of how things are served. It no longer has this pure request/response mode that HTTP has. HTTP is great - you get a request, you single-threadedily handle the request, you return a response, and then you just return to the top of the loop and keep going. It’s easy to write, CGI sorted this many decades ago, it’s an understood paradigm.

HTTP/2 - you can have concurrent requests that you can sort of work out with some multiple server processes, but you can also push information from the server in real time, and other things… And all this sort of brings on the same feeling like it’s all real time stuff that is no longer a request/response cycle.

At that point I sort of sat down and went, “Well, let’s think bigger than websockets. What would it take to bring Django to be a general protocol framework?” What would it take to be HTTP/1, HTTP/2, websocket, internet of things protocols coming out as well, several of those - they’re very lightweight of course, because the internet of things is very limited in bandwidth, but those also have API servers. What do we do for those?” and trying to envision this plan of “What would it take to build a framework, or build into Django a framework for the future of the web, the future of the internet? How do you write a system that handles all these different protocols and styles of communication, while still being like Django?” That’s the track I settled on back when I started Channels.