为什么使用同步功能get_channel_layer().send()
,则在处理结束时发送消息
def external_send(channel_name, data):
channel_layer = get_channel_layer()
send_sync = async_to_sync(channel_layer.send)
send_sync(
channel_name,
{
"type": "send_json",
"message": {"datetime": datetime.datetime.now().isoformat(), **data},
},
)
按预期在消费者工作中使用self.send()
这是我用于测试的消费者类别:
class TestConsumer(JsonWebsocketConsumer):
def connect(self):
self.accept()
def disconnect(self, close_code):
pass
def receive_json(self, content, **kwargs):
logger.debug(f"RECEIVE {content}")
self.send_json(
{
"id": 1,
"text": "Before sleep: self.send_json",
"datetime": datetime.datetime.now().isoformat(),
}
)
external_send(
self.channel_name, {"id": 2, "text": "Before sleep external_send"}
)
sleep(10) # Simuleting long processing
self.send_json(
{
"id": 3,
"text": "After sleep: self.send_json",
"datetime": datetime.datetime.now().isoformat(),
}
)
super().receive_json(content, **kwargs)
logger.debug("END")
我在前端收到订单
答案 0 :(得分:0)
答案是,每个渠道使用者都有自己的小运行循环。一次只能处理一个事件。这个单一的运行循环既用于从客户端(通过ws)接收的消息,也用于通过通道层上的组发送事件处理的消息。
如果您的receive_json
方法正在睡眠,则正在睡眠循环,因此不会发生其他任何事情。 receive_json
需要先完成,然后才能处理通过通道层发送的任何消息。
sleep
如果您确实需要sleep
使用方法从不进行同步,则这将使您的整个 python程序进入睡眠状态(一切都会进入睡眠状态) 。
使用异步使用者,您可以await asyncio.sleep(20)
,然后sleep
对该单个使用者的运行循环,其他websocket连接等将继续运行。对于任何其他长期运行的任务,也应如此,您应该使用异步使用者,然后使用异步线程池await
来运行这些长期运行的任务。
send_json
方法的分组。您应该在使用者handle_message
上创建一个方法,此方法可以调用send_json
,并且您的组发送的消息应该发送类型为handle.message
的消息。