'Django websockets and channels group_send not working

I started looking into websockets and I would liek to implement realtime communication between web-client (Angular 13) and Python app. As backend I used Django with implemented websockets and channels

As i am having problem i simplified code as much as i could so a lot of values are hardcoded for a sake to make it work. (Right now it is One WebClient and one Bot)

I implemented 2 Consumers. Bot and webclient:

class BotConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
    await self.accept()
    await self.channel_layer.group_add("bot","dev")

async def disconnect(self, close_code):
    await self.channel_layer.group_discard("bot","dev")

async def receive(self, text_data):
    await self.channel_layer.group_send("dev",{"type": "recv","text": "test"})
    print("Data sent to group")

class WebClientConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
    await self.accept()
    await self.channel_layer.group_add("client","dev")

async def recv(self,event):
    print("Consumer received smthing from channels")
    
async def disconnect(self, close_code):
    await self.channel_layer.group_discard("client","dev")

async def receive(self, text_data):
    print("Smthing received")

my channel_layer setup in Setting.py

CHANNEL_LAYERS = {
'default': {
    # 'BACKEND': 'channels_redis.core.RedisChannelLayer',
    # 'CONFIG': {
    #      "hosts": [('192.168.1.10', 6379)],
    # },
    "BACKEND": "channels.layers.InMemoryChannelLayer"
}}

I tried both Redis with local server running and in memory channels

My websocket's routing.py:

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r'live/bot', consumers.BotConsumer.as_asgi()),
    re_path(r'live/webclient', consumers.WebClientConsumer.as_asgi()),  
]

My behavior:

Django logs:

HTTP POST /core/UpdateAvailableServers 200 [0.07, 127.0.0.1:50494]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50497]
**WebSocket HANDSHAKING /live/bot [127.0.0.1:50498]**
**WebSocket CONNECT /live/bot [127.0.0.1:50498]**
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50501]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50504]
HTTP POST /core/GetBots 200 [0.00, 127.0.0.1:50524]
**WebSocket HANDSHAKING /live/webclient [127.0.0.1:50527]**
**WebSocket CONNECT /live/webclient [127.0.0.1:50527]**
HTTP POST /core/GetStatus 200 [0.01, 127.0.0.1:50528]
HTTP POST /core/UpdateAvailableServers 200 [0.02, 127.0.0.1:50531]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50534]
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50537]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50540]
HTTP POST /core/UpdateAvailableServers 200 [0.06, 127.0.0.1:50544]
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50547]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50550]
**Data sent to group**
HTTP POST /core/GetPostInfo 200 [0.00, 127.0.0.1:50554]
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50557]
HTTP POST /core/UpdateAvailableServers 200 [0.06, 127.0.0.1:50560]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50563]

As you can see in the log i got successfull websocket connection from my python app (BOT) and also angular app (WebClient) Both are added into group at connect Function.

Bot app will then send some data using websockets and they are suppose to be send to whole group which I will get confirmation as it is shown in log.

Problem is that My webclient will totally ignore this. recv method is never executed nor WebClient consumer will not show any activity on this action.

Is there some obvious mistake I am doing? (I can provide any additional info if needed)



Solution 1:[1]

You are not supposed to create a custom channel. Assign a custom group to the channel instead.

await self.channel_layer.group_add("bot",self.channel_name)

Also, send the socket message to the client group in the same channel.

await self.channel_layer.group_send("client",{
            "type":"recv",
            "message":text_data
        })

See the corrected implementation below.

class BotConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        await self.accept()
        await self.channel_layer.group_add("bot",self.channel_name)
        

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard("bot",self.channel_name)

    async def receive(self, text_data):
        
        await self.channel_layer.group_send("client",{
            "type":"recv",
            "message":text_data
        })

        print("Data sent to group")

class WebClientConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        await self.accept()
        await self.channel_layer.group_add("client",self.channel_name)

    async def recv(self,event):
        print("Consumer received smthing from channels")
        
    async def disconnect(self, close_code):
        await self.channel_layer.group_discard("client",self.channel_name)

    async def receive(self, text_data):
        print("Smthing received")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 PSN