渠道:为什么在处理结束时发送消息

问题描述 投票:0回答:1

为什么使用同步功能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")

在前端,我正在接收订单

  • {{id:1,文本:“睡前:self.send_json”,日期时间:“ 2020-05-29T14:30:58.226545”}]
  • {{id:3,文本:“入睡后:self.send_json”,日期时间:“ 2020-05-29T14:31:03.244865”}]
  • {{id:2,文本:“ Before sleep external_send”,日期时间:“ 2020-05-29T14:30:58.230164”}

enter image description here

django django-channels channels
1个回答
0
投票

作为回答,每个渠道使用者都会得到自己的小运行循环。一次只能处理一个事件。该单个运行循环既用于从客户端(通过ws)接收的消息,也用于通过通道层上的组发送事件处理的消息。

如果您receive_json方法正在睡眠,则正在睡眠循环,因此不会发生其他任何事情。 receive_json需要先完成,然后才能处理通过通道层发送的任何消息。

查看您的代码,还需要指出其他几点

同步sleep

如果您确实需要在方法中使用sleep 从不在同步方法中执行此操作,这将使您的entier python程序进入睡眠状态(一切都将进入睡眠状态)。

使用异步使用者,然后您可以await asyncio.sleep(20),然后将sleep您的运行循环用于该单一使用者,其他websocket连接等将继续运行。对于任何其他长时间运行的任务也是如此,您应该使用异步使用者,然后使用异步线程池来await这些长时间运行的任务。

您不应该尝试直接将发送分组到send_json方法。

您应该在使用者handle_message上创建一个方法,此方法可以调用send_json,并且您的组发送的消息应该发送类型为handle.message的消息。

© www.soinside.com 2019 - 2024. All rights reserved.