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

Django Channels动态生成用户专属WebSocket通知组问题及解决

踩坑记录:Django Channels无法动态生成用户专属WebSocket房间组名

最近在用Django Channels实现按用户划分的专属通知系统时,踩了个离谱的坑:每个用户连接WebSocket时,本该生成user_notification_{用户ID}的专属房间组名,但实际所有用户连接后,组名始终是user_notification_1,完全没法动态匹配当前用户。折腾半天终于找到原因,跟大家分享一下:

我的实现配置与代码

路由配置

application = ProtocolTypeRouter(
    {
        "websocket": AuthMiddlewareStack(
            URLRouter(websocket_urlpatterns)
        ),
    }
)

NotificationConsumer 实现

import json
from channels.generic.websocket import WebsocketConsumer

class NotificationConsumer(WebsocketConsumer):
    async def connect(self):
        self.user = self.scope["user"]
        if self.user.is_authenticated:
            self.room_group_name = f"user_notification_{self.user.id}"
        else:
            self.room_group_name = "anonymous"
        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):
        self.user = self.scope["user"]
        if self.user.is_authenticated:
            await self.send(
                text_data=json.dumps({"message": "pong"})
            )
        else:
            await self.send(
                text_data=json.dumps({"type": "error", "code": "UserNotAuthenticated"})
            )

    async def new_chat_message(self, event):
        await self.send(text_data=json.dumps(event.get("data")))

    async def connect_successful(self, event):
        await self.send(text_data=json.dumps(event.get("data")))

问题根源与解决方法

查了好久才定位到问题:我项目里用了dj-rest-auth,之前为了只使用Token认证,手动禁用了REST_SESSION_LOGIN配置:

# settings.py 中的错误配置
REST_SESSION_LOGIN = False

而Django Channels的AuthMiddlewareStack是依赖session认证来获取当前登录用户的!当REST_SESSION_LOGIN = False时,session认证被关闭,导致self.scope["user"]始终无法正确获取当前登录用户(我这里默认取到了ID为1的用户),自然没法生成对应用户ID的动态组名。

把REST_SESSION_LOGIN改回True之后,问题立刻解决:每个登录用户连接WebSocket时,都能正确生成user_notification_{用户ID}的专属房间组名,通知也能精准发送到对应用户的房间了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:22:36