免责声明:这可能是一个非常基本的问题,但我只是不明白这个概念,因此无法实现我想要的目标。
我正在尝试使用asyncio实现基本的echo客户端服务器。我从文档中包含的示例开始。
我想要实现的是持久连接,客户端可以随时除了立即connection_made 将一些数据发送到服务器然后读取响应(如果有的话)。连接必须在两端保持打开,直到明确关闭。
我正在使用协议样本。阅读其他问题/文档,似乎我可以使用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
永远不会执行。
答案 0 :(得分:1)
queue.get()永远不会在queue.put()之后唤醒的唯一原因是:您使用隐式循环创建队列(并且可能等待来自此循环的项目)但使用另一个循环实例推送数据。