难ban 2023-12-15 17:54 采纳率: 50%
浏览 11
已结题

django项目中服务端实现websocket长连接 主动实时推送消息给客户端

初学python,在django项目中使用channels
通过websocket长连接代替轮询,后端与前端建立连接后 在第三方调用接口生成数据后实时推送给前端
请问在websocketConsumer类怎么拿到对应的各个长连接?
如何在服务端主动实时给客户端推送消息?
谢谢!

  • 写回答

1条回答 默认 最新

  • 第九系艾文 2023-12-15 18:06
    关注

    类似这种的,通过group_send或者send,直接发送数据

    class MessageNotify(AsyncJsonWebsocketConsumer):
        def __init__(self, *args, **kwargs):
            super().__init__(args, kwargs)
            self.room_group_name = None
            self.disconnected = True
            self.username = ""
    
        async def connect(self):
            status, user_obj = await token_auth(self.scope)
            if not status:
                logger.error(f"auth failed {user_obj}")
                # https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent#status_codes
                await self.close(4401)
            else:
                logger.info(f"{user_obj} connect success")
                room_name = self.scope["url_route"]["kwargs"].get('room_name')
                username = self.scope["url_route"]["kwargs"].get('username')
                # data = verify_token(token, room_name, success_once=True)
                if username and room_name:
                    self.disconnected = False
                    self.username = username
                    self.room_group_name = f"message_{room_name}"
                    # Join room group
                    await self.channel_layer.group_add(self.room_group_name, self.channel_name)
                    await self.accept()
                else:
                    logger.error(f"room_name:{room_name} token:{username} auth failed")
                    await self.close()
    
        async def disconnect(self, close_code):
            self.disconnected = True
            if self.room_group_name:
                await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
    
        # Receive message from WebSocket
        async def receive_json(self, content, **kwargs):
            action = content.get('action')
            if not action:
                await self.close()
            data = content.get('data', {})
            if action == "message":
                data['uid'] = self.channel_name
                data['username'] = self.username
                # Send message to room group
                await self.channel_layer.group_send(
                    self.room_group_name, {"type": "chat_message", "data": data}
                )
            else:
                await self.channel_layer.send(self.channel_name, {"type": action, "data": data})
    
        async def userinfo(self, event):
            data = {
                'username': self.username,
                'uid': self.channel_name
            }
            await self.send_data('userinfo', {'data': data})
    
        async def chat_message(self, event):
            data = event["data"]
            data['time'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
            # Send message to WebSocket
            await self.send_data('message', {'data': data})
    
        async def send_data(self, action, content, close=False):
            data = {
                'time': time.time(),
                'action': action
            }
            data.update(content)
            return await super().send_json(data, close)
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月26日
  • 已采纳回答 12月18日
  • 创建了问题 12月15日

悬赏问题

  • ¥66 换电脑后应用程序报错
  • ¥50 array数据同步问题
  • ¥15 pic16F877a单片机的外部触发中断程序仿真失效
  • ¥15 Matlab插值拟合差分微分规划图论
  • ¥15 keil5 target not created
  • ¥15 C/C++数据与算法请教
  • ¥15 怎么找志同道合的伙伴
  • ¥20 如何让程序ab.eXe自已删除干净硬盘里的本文件自己的ab.eXe文件
  • ¥50 爬虫预算充足,跪巨佬
  • ¥15 滑块验证码拖动问题悬赏