gpt4 book ai didi

python - 了解 python asyncio 协议(protocol)

转载 作者:太空宇宙 更新时间:2023-11-04 09:42:39 26 4
gpt4 key购买 nike

我对 Python asyncio 和协议(protocol)的工作原理缺乏了解。

似乎相关的文档:
class asyncio.Protocol
Protocol.eof_received()状态机显示相关转换 AbstractEventLoop.run_until_complete(future)

echo tcp 客户端示例代码:

import asyncio

class EchoClientProtocol(asyncio.Protocol):
def __init__(self, message, loop):
self.message = message.encode()

def connection_made(self, transport):
self.transport = transport
self.write_data()

def data_received(self, data):
print('Data received: {!r}',len(data))
self.write_data()

def eof_received(self):
print("eof")
return True

def write_data(self):
print("write")
self.transport.write(self.message)

def connection_lost(self, exc):
print('The server closed the connection')
print('Stop the event loop')


loop = asyncio.get_event_loop()
message = 'Hello World!'

coro = loop.create_connection(lambda: EchoClientProtocol(message, loop),
'127.0.0.1', 5676)
loop.run_until_complete(coro)
print("done")

在回显服务器上连接时的输出:

write
Data received: {!r} 12
write
done

据我了解,这应该一直运行到连接关闭。

发件人:Connection callbacks

connection_made() 和 connection_lost() 在每次成功连接时只调用一次。将在这两个方法之间调用所有其他回调,这样可以更轻松地在协议(protocol)实现中进行资源管理。

还有状态机:

start 
-> connection_made
[-> data_received]*
[-> eof_received]?
-> connection_lost
-> end

但是,函数 EchoClientProtocol.connection_lost 永远不会被调用并且loop.run_until_complete(coro) 在协议(protocol)完成之前终止。

问题是:
如何获得包装协议(protocol)的协程/ future ,使协程在达到协议(protocol)的结束状态时完成并在此类事件上返回 loop.run_until_complete。

最佳答案

正如 Sraw 的回答所指出的,loop.create_connection 是一个协程,一旦它创建了传输/协议(protocol)对就会返回。因此,您需要运行另一个协程(或等效对象),它将使事件循环保持事件状态,以便发生有趣的事情。

how to run loop until protocol internal state reaches state end without explicitly closing loop

您不一定需要关闭或停止循环。如果我没听错的话,你会希望避免难看的 run_forever,而是编写如下内容:

transport, protocol = loop.run_until_complete(coro)
transport.close()
loop.run_until_complete(protocol.wait_connection_lost())

虽然 wait_connection_lost() 确实没有随 asyncio 一起提供,但您提供了协议(protocol)实现,因此您可以轻松地为您的协议(protocol)创建一个:

class EchoClientProtocol(asyncio.Protocol):
# your other methods are unchanged

def __init__(self, message, loop):
self.message = message.encode()
self.__done = loop.create_future()

def connection_lost(self, exc):
# the value passed to set_result will be transmitted to
# run_until_complete(protocol.wait_connection_lost()).
self.__done.set_result(None)

# When awaited, resumes execution after connection_lost()
# has been invoked on this protocol.
def wait_connection_lost(self):
return self.__done

关于python - 了解 python asyncio 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51079150/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com