Package: django-actioncable
READMEThis package provides Rails Action Cable support to Django Channels.InstallPlease make sureDjango channelsis already working in Django project before installing this package.$pipinstalldjango-actioncableIn theasgi.py, we have code like thisimportosfromchannels.routingimportProtocolTypeRouter,URLRouterfromdjango.core.asgiimportget_asgi_applicationfromdjango_app.coreimportroutingos.environ.setdefault("DJANGO_SETTINGS_MODULE","django_app.settings")application=ProtocolTypeRouter({"http":get_asgi_application(),"websocket":URLRouter(routing.urlpatterns)})Notes:Thewebsocketprotocol would be handled byURLRouter(routing.urlpatterns)In the routing file, we add below code:fromactioncableimportActionCableConsumerurlpatterns=[path("cable",ActionCableConsumer.as_asgi()),]Notes:So all the Websocket requests sent tows://localhost:8000/cablewould be handled byActionCableConsumerTheActionCableConsumerwould then dispatch the request to the corresponding channel class.We can add below code to the routing file to register the channel class.fromactioncableimportActionCableConsumer,CableChannel,cable_channel_register@cable_channel_registerclassChatChannel(CableChannel):def__init__(self,consumer:ActionCableConsumer,identifier_key,params=None):self.params=paramsifparamselse{}self.identifier_key=identifier_keyself.consumer=consumerself.group_name=Noneasyncdefsubscribe(self):self.group_name=f"chat_{self.params['pk']}"awaitself.consumer.subscribe_group(self.group_name,self)asyncdefunsubscribe(self):awaitself.consumer.unsubscribe_group(self.group_name,self)We create aChatChannel, which inherits from theCableChannel.Thecable_channel_registerdecorator would register theChatChannelclass to theActionCableConsumer.In thesubscribecallback method, we get the room pk from theself.paramsdict and subscribe the channel to the groupchat_{pk}.In theunsubscribecallback method, we unsubscribe the channel from the group.HTML<!DOCTYPE html><html><head><title>ActionCable Example</title></head><body><divid="messages"></div><scriptsrc="https://cdn.jsdelivr.net/npm/@rails/actioncable@7.1.2/app/assets/javascripts/actioncable.js"></script><script>document.addEventListener("DOMContentLoaded",function(){// Create a consumer object to connect to the ActionCable serverconstcable=ActionCable.createConsumer();// Define a channel and its corresponding functionsconstchannel=cable.subscriptions.create({channel:"ChatChannel",pk:"1"},{connected(){console.log("Connected to the chat channel.");},disconnected(){console.log("Disconnected from the chat channel.");},received(data){// Display the received messageconstmessagesDiv=document.getElementById("messages");constmessageDiv=document.createElement("div");messageDiv.innerText=data;messagesDiv.appendChild(messageDiv);}});});</script></body></html>Notes:We use theActionCable.createConsumer()to create a consumer object to connect to the ActionCable server.ThechanneisChatChannel, so theChatChannelwe just created will be used to handle the request.In the client, we can pass room pk to theChatChannelbypk: "1", and in the backend we can get it in theself.paramsIn this case, the channel willsubscribeto thechat_1group.TestLaunch Django shell, and run below code:fromactioncableimportcable_broadcastcable_broadcast("chat_1",message="Hello World")You should be able to see the message appear on the web page.cable_broadcastis a wrapper of Django Channelasync_to_sync(channel_layer.group_send)method call, we can use it in Django view or external process such as Celery worker.Themessagevalue can also be Python dict, and in javascript we can get it in thedataparameter of thereceivedcallback method.