Seeking advice on a custom channels implementation

Hi, django people, I’m thinking about writing a custom channels implementation, so I thought I can use some advice on that.

I have a WSGI application so the main goal is to be able to use websockets, there are no requirements for channels/groups etc.

In search for inspiration I found the Anycable project (https://docs.anycable.io/) and was surprised that it was the same type of an “all in one” solution as django channels is. It supports channels/groups and AFAIK uses queues under the hood.

However, I think, a much simpler design is possible. Suppose you have a websocket server that just holds connections by name. So you can send and receive messages using the connection name. All the rest - grouping into channels and using queues - can be done on “application side”. The websocket server shouldn’t be aware of it.

An example API

def connect(request):
  return {'accept': True, 'name': 'user1'}

def on_message(request):
   # coming from request.name

And of course, you can send a message, using the connection name: send(name, message)

What do you think? What are the troubles with this approach?

Yes, a much simpler design is possible. It’s all a question of what features you’re willing to give up.

I have written websocket servers using the python websockets library as a custom Django management command. It allows me to add and retrieve data from a database using Django models, from a browser websocket connection. It was the simplest method I could come up with for that specific task. It actually works quite well.

Why should I write all that code when it’s already provided for me within the Channels environment?

So you’re not going to perform any authentication on the request? Anyone is going to be able to connect to your websocket server? (That is a valid approach in a number of different environments.)

I would say the “trouble” (I’d probably prefer the term “limitations”) with this type of approach is that for it to be truly usable, there’s a lot of code left to write.

I think an appropriate analogy might be along the same lines as a discussion around using DRF. If you have just one or two views that need to return JSON in your Django site, then DRF is probably a lot more than you need. However, if you’re building out a full API that needs to handle things like nested objects, token authentication, custom and selectable serialization formats, etc, then you’re better off using DRF.

I believe the same applies here. You can start out simple - like with a websocket server as I described above. But then as you keep adding functionality, you realize at some point what you’ve done is recreated “Channels-lite”.

For example, what specifically are the types of messages that you’re looking to transfer? Are you looking for messages to act as an RPC? That’s really a core feature of Channels - and probably its most significant function from my perspective.

Are you only returning JSON? Or are you looking to return HTML such as using Channels with HTMX? (Being able to call Django views is a plus there.)

What about handling transient connects/disconnects? (Always an issue if you’re working with mobile devices.)

So, only sending / receiving data from a browser? Sure, go the simpler route. But if you want real Django-integration with the rest of your Django project, I don’t see why you would want to build that yourself.

Actually you are right, the idea is stupid. At least I’ve changed my mind for now. Thanks a lot!