django 通道异步消费者阻塞 http 请求

django channels async consumer blocking on http request

我有以下异步消费者:

class MyAsyncSoncumer(AsyncWebsocketConsumer):
    
    async def send_http_request(self):

        async with aiohttp.ClientSession(
                timeout=aiohttp.ClientTimeout(total=60)  # We have 60 seconds total timeout
        ) as session:
            await session.post('my_url', json={
                'key': 'value'
            })

    async def connect(self):
        await self.accept()

        await self.send_http_request()

    async def receive(self, text_data=None, bytes_data=None):
        print(text_data)

在这里,在 connect 方法上,我首先接受连接,然后调用一个使用 aiohttp 发出 http 请求的方法,超时时间为 60 秒。假设我们发送请求的 url 是不可访问的。我最初的理解是,由于所有这些方法都是协程,当我们在等待对请求的响应时,如果我们收到消息,将调用 receive 方法,我们可以在请求完成之前处理消息。然而,实际上,我只是在请求超时后才开始接收消息,所以看起来消费者正在等待 send_http_request 完成才能接收消息。

如果我替换

await self.send_http_request()

asyncio.create_task(self.send_http_request())

我可以在发出请求时接收消息,因为我不等待它在 accept 方法上完成。

我的理解是,在第一种情况下,在等待请求时,我也可以接收消息,因为我们在这里使用不同的协程,但事实并非如此。会不会是整个消费者实例作为一个协程工作?有人可以澄清这里发生了什么吗?

django 频道中的每个消费者 运行 他们自己的 运行 循环(异步任务)。但这是每个消费者而不是每个消息,所以如果你正在处理一条消息并且你在等待某些东西,那么整个 运行 那个 websocket 连接的循环正在等待。