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

Django Channels+Redis开发聊天应用遇AsyncConsumer参数缺失错误求助

解决Django Channels中AsyncConsumer.__call__() missing 1 required positional argument: 'send'错误

核心问题定位

这个错误的直接原因是ASGI路由中未用as_asgi()方法包装Consumer类。Channels 3.0+版本要求将Consumer类转换为ASGI可调用对象,否则会触发参数不匹配的异常。此外你的代码还有两处细节错误需要修正:


分步修复方案

1. 修正ASGI路由配置

在asgi.py的WebSocket路由中,必须用as_asgi()包装Consumer类:

  • 原错误代码:
    ws_patterns = [
        path('ws/test/',TestConsumer)
    ]
    
  • 修改后:
    ws_patterns = [
        path('ws/test/',TestConsumer.as_asgi())
    ]
    

同时建议把HTTP协议的ASGI应用也加入ProtocolTypeRouter,保证Django的HTTP请求正常处理:

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    'websocket' : URLRouter(ws_patterns)
})

2. 修复Consumer类的两处错误

  • receive方法参数缺失:WebsocketConsumer的receive方法必须接收text_data或bytes_data参数,否则会触发后续异常:
    def receive(self, text_data=None, bytes_data=None):
        # 可在此处添加消息处理逻辑
        pass
    
  • group_add参数顺序颠倒:channel_layer.group_add的第一个参数是组名,第二个是当前通道名,原代码顺序错误会导致无法正常加入组:
    async_to_sync(self.channel_layer.group_add)(
        self.room_group_name, self.channel_name  # 组名在前,通道名在后
    )
    

另外建议在disconnect方法中添加离开组的逻辑,避免资源泄漏:

def disconnect(self, close_code):
    async_to_sync(self.channel_layer.group_discard)(
        self.room_group_name, self.channel_name
    )

完整修正后代码

asgi.py

"""
ASGI config for chatapp project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter,URLRouter
from django.urls import path
from home.consumers import TestConsumer

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chatapp.settings')

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    'websocket' : URLRouter([
        path('ws/test/',TestConsumer.as_asgi())
    ])
})

consumers.py

from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
import json

class TestConsumer(WebsocketConsumer):
    def connect(self):
        self.room_group_name = "test_consumer_group"
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name, self.channel_name
        )
        self.accept()
        self.send(text_data=json.dumps({'status':'connected'}))

    def receive(self, text_data=None, bytes_data=None):
        # 这里可以添加消息处理逻辑,比如转发到组内
        pass

    def disconnect(self, close_code):
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name, self.channel_name
        )

内容的提问来源于stack exchange,提问作者Jaswanth Ch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:15:30