You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Channels无法接收自定义库触发的事件问题排查

Django Channels 自定义库触发事件无法被Consumer接收排查

使用Django Channels时遇到自定义库触发的事件无法被Consumer接收的问题,日志仅打印到"Sendiong now to group"后无后续输出,以下是相关代码和排查信息:

Consumer类代码

from channels.generic.websocket import AsyncWebsocketConsumer
from channels.layers import get_channel_layer
import json

class TradeSession(AsyncWebsocketConsumer):
    async def connect(self):
        print("In Consumer Now")
        self.room_name = "test_consumer"
        self.room_group_name = "test_consumer_group"
        await self.channel_layer.group_add(self.room_name, self.channel_name)
        await self.accept()

    async def disconnect(self, close_code):
        print("Disconnected Now")
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
        raise channels.exceptions.StopConsumer()

    async def receive(self, text_data=None, bytes_data=None):
        print("Data Recieved")
        pass

    async def send_number(self, event):
        print("in Send number Send event", event)
        number = event["price"]
        print("Actually sending now ", number)
        await self.send(text_data=json.dumps({"price": number}))

触发事件的Communicator库代码

from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

class Communicator:
    def __init__(self):
        pass
    
    def send_data_to_channel_layer(self, data, group_name):
        group_name = "test_consumer_group"
        print("In library sending data")
        channel_layer = get_channel_layer()
        print("Sending now to group", group_name)
        async_to_sync(channel_layer.send)(group_name, {
            "type": "send.number",
            "price": data['price'],
        })
        # print("Message sent to group")

Channels配置

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
    },
}

已确认信息

  • WebSocket连接正常,客户端验证通过
  • Redis服务在本地6379端口正常运行

问题排查与修复

1. 组名匹配错误

Consumer的connect方法中,group_add的第一个参数应该是组名(self.room_group_name),但当前代码传入的是房间名(self.room_name),导致频道加入的组和事件发送的组不匹配,事件无法被Consumer接收。

修复后的connect方法:

async def connect(self):
    print("In Consumer Now")
    self.room_name = "test_consumer"
    self.room_group_name = "test_consumer_group"
    # 修正:将频道加入目标组
    await self.channel_layer.group_add(self.room_group_name, self.channel_name)
    await self.accept()

2. 事件发送方法错误

向组发送事件需要使用channel_layer.group_send方法,而不是channel_layer.send(后者用于给单个频道发送消息)。当前代码用错方法,导致事件无法广播到组内的Consumer。

修复后的send_data_to_channel_layer方法:

def send_data_to_channel_layer(self, data, group_name):
    group_name = "test_consumer_group"
    print("In library sending data")
    channel_layer = get_channel_layer()
    print("Sending now to group", group_name)
    # 修正:使用group_send广播到组
    async_to_sync(channel_layer.group_send)(group_name, {
        "type": "send.number",
        "price": data['price'],
    })
    print("Message sent to group")

3. 断开连接时的组移除错误

disconnect方法中使用了错误的group_discard方法,正确的移除组方法是group_remove,且无需手动抛出StopConsumer(AsyncWebsocketConsumer会自动处理)。

修复后的disconnect方法:

async def disconnect(self, close_code):
    print("Disconnected Now")
    # 修正:使用group_remove从组中移除频道
    await self.channel_layer.group_remove(self.room_group_name, self.channel_name)

内容的提问来源于stack exchange,提问作者Naresh Joshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:13:20