【问题标题】:asyncio with persistent connections具有持久连接的异步
【发布时间】:2014-11-05 11:37:22
【问题描述】:

免责声明:这可能是一个非常基本的问题,但我只是不了解这个概念,因此无法实现我想要的。

我正在尝试使用 asyncio 实现基本的 echo 客户端服务器。我从文档中包含的示例开始。

我想要实现的是一个持久连接,客户端可以在任何时候除了立即连接向服务器发送一些数据,然后读取响应(如果有的话)。连接必须在两端保持打开状态,直到显式关闭。

我正在使用协议示例进行此操作。阅读其他问题/文档,似乎我可以使用loop.call_later() 来实现它,但这真的是一个好的解决方案吗?理想情况下,我希望使用Queue 能够立即响应新数据包。

我最终得到了这段代码,从 ´MyProtocol.init` 调用:

    @asyncio.coroutine
    def writer():
        global out_queue
        while True:
            packt = yield from out_queue.get()
            print("yeahhh packet yummy")
            data = bytes(packt.to_json(), 'ascii')
            self.transport.write(data)

    asyncio.async(writer())

但这无济于事。我假设当从主客户端代码插入新项目时,这会立即打印出消息。什么都没有发生...

进一步调试显示队列正在被填满,但 out_queue.get() 协程永远不会返回。最初 out_queue.put 甚至将项目直接放入服务员中以进行初始 .get() 调用,但就好像循环没有运行一样。它与用于整个客户端连接的循环相同(我创建了一个新循环,因为我将所有内容都放入了一个线程中)。我已经检查过了,从 .put() 调用中进行的适当调用都是针对这个循环的。

哦,以防万一:我在 python 3.3 上运行它,通过 pip 安装 asyncio。

更新:这是我尝试将项目插入队列的方式:

def send_packet(loop, queue, packet):
    # this runs in main thread, not the loop thread

    def f():
        print("putting packet into queue")
        queue.put_nowait(packet)  # MUST NOT use .put() as it's a coroutine

    loop.call_soon_threadsafe(f)
    # !!! next one doesn't work !!!
    # loop.call_soon_threadsafe(any_normal_function_with_coroutine_calls())

print 永远不会执行。

【问题讨论】:

    标签: python-3.x python-asyncio


    【解决方案1】:

    queue.get() 在 queue.put() 之后永远不会唤醒的唯一原因是:您使用隐式循环创建队列(并且可能等待此循环中的项目)但使用另一个循环实例推送数据。

    【讨论】:

    • 好吧,实际上我是从另一个线程推送它们的。但我也尝试将它们从添加了 `loop.call_soon_threadsafe()' 的函数中推送出来,但该函数根本没有被调用。
    • NVM,文档没有特别清楚地说明如何使用 call_soon_threadsafe。我认为任何旧功能都可以,但事实证明它不是......问题更新了正确的解决方案
    • call_soon、call_later 和 call_soon_threadsafe 接受常规函数,而不是协程。新鲜的 asyncio 对其进行了检查。
    • 不,它可以是任何功能。但是,如果您传递生成器函数(内部带有yieldyield from 的函数),asyncio 将不会展开(unyield)该生成器和代码将不会执行。 asyncio.async 创建 asyncio.Task 执行生成器展开。
    • 这就是任务展开的工作原理:它安排下一个切片的执行从 yield 到下一个 yield 到 loop.call_soon.call_soon 需要下一个循环迭代并请求套接字轮询(可能是即时且非常快速的,但无论如何它是系统调用)以执行。
    猜你喜欢
    • 2011-03-09
    • 2019-04-18
    • 2021-08-31
    • 2017-05-21
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    相关资源
    最近更新 更多