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

Django Channels group_send问题:消息未按间隔发送而是批量送达

Django Channels 4.0.0 group_send 消息批量送达问题

使用Django Channels 4.0.0时遇到异常:在循环中添加延迟调用group_send发送消息,消息未按预期间隔逐条送达客户端,而是在receive函数执行完毕后一次性全部发送。

最小复现代码

ChatConsumer 代码

from channels.generic.websocket import AsyncWebsocketConsumer
import json
import asyncio

class ChatConsumer(AsyncWebsocketConsumer):
    room_name: str
    room_group_name: str

    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = f'chat_{self.room_name}'

        await self.channel_layer.group_add(self.room_group_name, self.channel_name)
        await self.accept()

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

    async def receive(self, text_data=None, bytes_data=None):
        for i in range(0, 50):
            message = f'Message ({i})'
            await self.channel_layer.group_send(
                self.room_group_name,
                {
                    'type': 'chat.message',
                    'message': message
                }
            )
            await asyncio.sleep(0.1)

    async def chat_message(self, event):
        await self.send(text_data=json.dumps({
            'message': event['message']
        }))

settings.py 相关配置

# 两种通道层均存在该问题
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels.layers.InMemoryChannelLayer',
#       'BACKEND': 'channels_redis.core.RedisChannelLayer',
#       'CONFIG': {
#           'hosts': [(os.environ.get('REDIS_HOST', 'localhost'), os.environ.get('REDIS_PORT', '6379'))],
#       },
    },
}

asgi.py 代码

from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import os

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

django_asgi_app = get_asgi_application()

from django.urls import path
from core.consumers.chat_consumer import ChatConsumer

application = ProtocolTypeRouter(
    {
        'http': django_asgi_app,
        'websocket': URLRouter([
            path('ws/chat/<str:room_name>/', ChatConsumer.as_asgi()),
        ]),
    }
)

预期与实际行为

  • 预期:客户端每隔0.1秒收到一条消息
  • 实际:所有消息在总延迟5秒后(即receive函数执行完成时)同时送达

已执行的排查步骤

  • 尝试RedisChannelLayer和InMemoryChannelLayer两种通道层,问题均存在
  • 使用Postman、Microsoft Edge等不同WebSocket客户端测试,结果一致
  • 确认无其他中间件或额外层干扰
  • 直接调用send发送消息(绕过group_send)时,消息可实时送达,符合预期
  • 分别使用runserver和直接启动daphne两种方式运行服务,问题依旧

请问这是group_send的固有特性,还是我遗漏了某些配置?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:22:31