难ban 2024-04-23 15:01 采纳率: 50%
浏览 2
已结题

http请求推送消息到长连接,若当前长连接不存在,如何在channellayer中清除当前消息

使用框架:django + channels
我写了一个http请求async_receive_msg
调用如下async_receive_msg方法,但当前通道名已断开连接,
虽然方法调用成功,但是实际上消息是不能发送出去的,导致消息在通道中堆积,我该如何操作才能删除这些没用的消息?
或者如何校验当前通道是否仍在连接,如何丢弃这些消息?

@csrf_exempt
@async_to_sync
async def async_receive_msg(request):
    """
        调用当前方法
    """
    try:
        room = data.get('room')
        channel_name = await get_channel_name_by_code(room)
        if not channel_name:
            logger.info('推送点赞信息给房间{}时检测到当前房间未连接'.format(room))
            return JsonResponse({'result': 1, 'msg': 'room{} is not connected!'.format(room)})
 
        await channel_layer.send(channel_name, {
            "type": "group_message",
            "message": "msg",
        })
        return JsonResponse({'result': 1, 'msg': 'success'})
    except Exception as e:
        logger.error(e)
        return JsonResponse({'result': 2, 'errorMsg': str(e)})
 
class AsyncConsumer(AsyncWebsocketConsumer):
        async def connect(self):
            await self.accept()
        
        async def disconnect(self, close_code=None):
            ...
        
        async def group_message(self, event):
        """
            消息推送
        """
        await self.send(text_data=json.dumps({
            'result': 1,
            "message": event.get("message")
        }))
  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-23 15:01
    关注

    引自免费微信小程序:皆我百晓生

    为了确保消息只被发送给在线的用户,并且在长连接断开后不再尝试发送消息,你需要对async_receive_msg函数进行一些修改。首先,我们需要添加一个检查通道是否连接的方法。接下来,在发送消息之前,先调用这个方法。

    以下是修改后的代码:

    from channels.db import database_sync_to_async
    from django.db.models.query_utils import Q
    
    def is_channel_connected(channel_name):
        # 假设你有一个UserChannel模型,它包含channel_name和user_id字段
        UserChannel = database_sync_to_async(UserChannel.objects.select_related('user'))
    
        user_channel = UserChannel.filter(Q(user__is_active=True) & Q(channel_name=channel_name)).first()
    
        return bool(user_channel)
    
    @csrf_exempt
    @async_to_sync
    async def async_receive_msg(request):
        """
            调用当前方法
        """
        try:
            room = data.get('room')
            channel_name = await get_channel_name_by_code(room)
            
            if not is_channel_connected(channel_name):
                logger.info('推送点赞信息给房间{}时检测到当前房间未连接'.format(room))
                return JsonResponse({'result': 1, 'msg': 'room{} is not connected!'.format(room)})
    
            await channel_layer.send(channel_name, {
                "type": "group_message",
                "message": "msg",
            })
            return JsonResponse({'result': 1, 'msg': 'success'})
        except Exception as e:
            logger.error(e)
            return JsonResponse({'result': 2, 'errorMsg': str(e)})
    

    这里我们假设有一个名为UserChannel的数据库模型,它与用户关联并存储了通道名称(channel_name)。is_channel_connected函数会查询这个模型,判断用户是否还在线。如果用户已经离线,那么返回False,否则返回True

    注意,这个示例中的UserChannel模型以及其关联的用户模型可能需要根据你的具体实现进行调整。关键是确保你有一种方式可以跟踪哪个用户正在通过特定的通道名称连接。

    现在,当async_receive_msg尝试发送消息时,它会首先检查通道是否仍然连接。如果连接断开,它将不会尝试发送消息,从而防止消息积压。如果你的项目中有其他处理用户连接状态的方法,只需相应地调整is_channel_connected函数即可。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月4日
  • 创建了问题 4月23日

悬赏问题

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