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
相关产品推荐
相关产品推荐

