Python中关于Channels 2.0的使用问题求助

问题背景:

我需要在后台订阅 redis 的消息,一有消息就给前端推信息。所以我这么做了:

    async def connect(self):
        logger.info("websocket connected.")
        redis_conn = StrictRedis(**settings.REDIS_DB)
        self.ps = redis_conn.pubsub()
        await self.ps.subscribe(settings.REDIS_CHANNELS)
    await self.accept()

async def disconnect(self, code):
    logger.info("websocket disconnected.")
    await self.ps.unsubscribe()
    await self.close()

async def receive(self, text_data=None, bytes_data=None):
    logger.info("websocket received data.\n%s" % text_data)
    try:
        data = json.loads(text_data)
        self.user_id = data['payload'].get('user_id')
    except json.JSONDecodeError:
        await self.close()

    while True:
        # 获取 redis 的消息
        msg = await self.get_msg_from_queue()
        if not msg:
            continue
        logger.info("get msg %s" % msg)
        await self.send(text_data=json.dumps(msg))

打开前端页面的时候,链接成功 websocket 会立马发一个信息,来对接,后端确认以后开始等 redis 的消息,这里我使用的 while 循环,就是因为这个 while 循环,导致我前端断开 websocket 链接以后,后端不会触发 disconnect()函数,所有就没有关闭这个实例,导致后端不断报这个错误:

WARNING  Application instance <Task pending coro=<AsyncConsumer.__call__() 
running at /xxx/venv/lib/python3.6/site-packages/channels/consumer.py:54> 
wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7fade64e0678>()]>> 
for connection <WebSocketProtocol client=['127.0.0.1', 49204] path=b'/listen'> 
took too long to shut down and was killed.

求助 V 站大佬,我该如何在 while 循环中来判断当前客户端是否断开呢?


Python中关于Channels 2.0的使用问题求助

4 回复

如果你用的是 channels-redis,看看源码,等待消息的逻辑已经实现了,你不用重复搞一遍。
你这样搞等于把接受消息端的给阻塞了。


我无法理解你的问题

不要在 receive 中阻塞,而是在一个单独的进程中 pull 消息,然后推送给响应的 client

http://channels.readthedocs.io/en/latest/introduction.html#cross-process-communication

好的,谢谢指点。

回到顶部