【问题标题】:Python asyncio streams: No stop bytePython asyncio 流:没有停止字节
【发布时间】:2022-12-22 20:30:51
【问题描述】:

当我编写一个从服务发送和接收一些 JSON 的程序时,我偶然发现了一个挑战。服务器不发送停止字节(不会说谎,我花了几个小时才意识到这一点),它只是逐字节的 JSON。甚至没有单引号。

在放弃并执行一个 while 循环之前,我一直在寻找一个优雅的解决方案,该循环不断地在缓冲区中逐字节添加并检查它是否是有效的 JSON。

有没有人曾经处理过类似的事情?

【问题讨论】:

  • 一个常态需要添加一些代码,以便答案可以建立在它之上。但提前:如果您正在从套接字读取数据,您可以要求更大的字节数:如果可用数据总量小于该值,则读取不会阻塞 - 您可以在读取后检查是否有有效的 JSON这个更大的块。然后,如果有开放的 JSON 括号,只需重复读取。
  • @jsbueno 我尝试过类似的方法,但是 StreamReader 的 read 方法仅在达到声明的数量 (n) 时才返回接收到的数据。不幸的是,这些 JSON 消息实际上并没有固定的大小。另外,显然“停止字节”应该命名为 EOF ...

标签: python python-asyncio


【解决方案1】:

通过逐字节读取并将其添加到缓冲区来解决问题。每次读取一个字节时,我都会检查缓冲区是否是有效的 JSON。

def is_json(string: str) -> bool:
    try:
        json.loads(string)
    except ValueError as e:
        return False
    return True


class MyClient:
# ... my implementation of asyncio's client streams using OOP...

    async def receive(self) -> str:
    # Method used to read data from the server
        msg = ''
        while self.connected:
            data = await self.reader.read(1)
            log.debug(f"Read: {data}")
            msg = msg + data.decode()
            if is_json(msg):
                log.info(f"Received: {msg}")
                return msg
        log.warning(f"Client disconnected!")

希望这对某人有帮助。

另外,如果您有更好/更优雅的选择,请分享。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多