Django websockets 和通道 group_send 不工作

Django websockets and channels group_send not working

我开始研究 websockets,我希望在网络客户端 (Angular 13) 和 Python 应用程序之间实现实时通信。作为后端,我使用 Django 实现了 websockets 和通道

因为我有问题,所以我尽可能地简化了代码,所以为了让它工作,很多值都被硬编码了。 (现在是一个 WebClient 和一个 Bot)

我实现了 2 个消费者。机器人和网络客户端:

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")

我的channel_layer设置在Setting.py

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

我在本地服务器 运行 和内存通道

中尝试了 Redis

我的 websocket 的 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()),  
]

我的行为:

Django 日志:

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]

正如您在日志中看到的那样,我从我的 python 应用程序 (BOT) 和 angular 应用程序 (WebClient) 获得了成功的 websocket 连接,两者都在连接函数中添加到组中。

Bot 应用程序随后将使用 websockets 发送一些数据,它们应该被发送到整个组,我将得到确认,如日志中所示。

问题是我的网络客户端将完全忽略这一点。 recv 方法永远不会执行,WebClient 消费者也不会在此操作上显示任何 activity。

我是否犯了明显的错误? (如果需要,我可以提供任何其他信息)

您不应该创建自定义频道。改为将自定义组分配给频道。

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

另外,将套接字消息发送到同一个频道的客户端组。

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

请参阅下面更正后的实施。

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")