异步协议的三重实现

trio-protocol的Python项目详细描述


#trio协议

它在[`trio`](https://github.com/python trio/trio)之上实现了"asyncio.transport"接口和基本的异步类,如"asyncio.task",以帮助移植"asyncio"库。其思想是允许"trio"运行一个[`asyncio.protocol`](https://docs.python.org/3/library/asyncio protocol.html protocols),从而使单个代码基可以在两个框架上运行。

让您在"trio"上运行"asyncio"代码而不做任何更改不是"trio protocol"的目标**。如果需要,请查看[`asyncio trio`](https://github.com/python trio/trio asyncio)。



您可以使用它来支持一些基本的"异步"服务器。但是,它缺少:

-对客户端的支持(仅对服务器进行了测试)
-一个测试套件。
-在生产环境中运行它的可靠体验。
-可能是异步代码在野外使用的有用/必需方法的实现,应该添加这些实现。



refixed string protocol.py`来自python3示例库(https://github.com/eliben/python3-samples/blob/master/async/asyncio-len-prefixed-string-protocol.py),位于"trio"之上。

如果您跟踪该链接,您会看到该模块首先实现了"asyncio.protocol"的子类,然后进一步对其进行子类化。最终,实现的协议从客户端读取以长度为前缀的字符串,并发送回一条"确定"消息。


在文件底部,您将找到以下启动服务器的代码:

``python
loop=asyncio.get_event_loop()
coro=loop.create_server(mystringreceiver,'127.0.0.1',5566)
server=loop.运行直到完成(coro)
print({}上的服务)。format(server.sockets[0].getsockname())

try:
loop.run庀ever()
除了键盘中断:
print("exit")
最后:
server.close()
loop.close()
````

这将创建一个在端口5566上运行的"异步"服务器。到该端口的每个连接都将由"myStringReceiver"协议提供服务。具体来说,"loop.create_server()"将设置服务器的套接字(因为它是一个"async"函数,在等待之前它不会做任何事情,在本例中,我们是通过"loop.run_until_complete"来做的)。无论何时有人连接到服务器,asyncio都会安排一个任务来处理连接。我们运行"loop.run_forever()"使循环处于活动状态并处理这些任务。

现在让我们在"trio"上运行此命令。将此部分代码替换为:

``python
import trio
from trio_protocol import run_server

trio.run(run_server,mystringreceiver,'127.0.0.1',5566)
````

代码比原来的短了一点,部分原因是设置trio没有那么冗长,部分原因是我们做的更少:我们不能干净地处理"keyboardinterrupt",并且一旦准备好接受连接,就不会打印消息。相反,"trio_protocol.run_server"是一个快捷方式,它为我们做任何事情:它打开一个托儿所,启动一个服务器,并在该服务器上运行"asyncio.protocol"。

如果我们想更准确地复制原始代码,我可以这样做:

``python
import trio
from trio_protocol import create_server

async def run_server()用法:
与trio异步。open_nursery()作为苗圃:
server=await create_server(苗圃,mystringreceiver,'127.0.0.1',5566)
print({}上的服务)。format(server.sockets[0].getsockname())

尝试:
trio.run(run嫒server)
除了键盘中断:
print("exit")
``````

`` trio嫒protocol.creATE U服务器``将开始监听套接字。它将返回一个"trio_protocol.server"对象,用于镜像"asyncio.server"。然后您可以运行自己的代码,服务器运行在背景,类似于"asyncio"版本。

>;>;注意:要测试此服务器,可以使用:
>;`python-c"import struct;print((b'%shello world'%struct.pack('&l t;l',12)).decode('ascii'))";nc localhost 5566'


o循环

如果协议使用"asyncio"循环,例如启动后台任务,则可以使用"trio\u protocol.loop",这是一个类似循环的类,支持一些常用的方法,如"稍后调用"或"创建任务"。大多数协议都是为了接受一个"loop"参数而编写的,所以您应该这样做:

`` python
导入functools
从trio协议导入循环导入trio
,运行服务器

async def run-server():
与trio异步。open\u nursery()作为nursery:
loop=loop(nursery)
protocol_factory=functools.partial(myprotocol,loop=loop)
等待create_server(nursery,protocol_factory,'127.0.0.1',5566)


trio.run(run_server)
`````

协议要生成的后台任务现在在指定给"trio_protocol.loop"的托儿所内运行。

注意:严格要求要运行的协议类使用显式循环。大多数"asyncio"接口的编写方式是这样的:当未传递显式循环时,将自动使用当前全局循环。这不起作用,因为您最终会使用"asyncio"循环。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java使用哪个地图/集合?   bluej Java:计算税   由于性能问题,java双精度字符串替代方案   java Eclipse CDT生成设置因重新启动而丢失   如何在java控制台中显示字节流值   java获取url地址,其中是包含我的页面的iframe   java 403禁止的spring启动API调用错误?   如果一个方法返回true,java将停止计时器   使用JavaNIO获取文件创建日期   在Java中从整数转换为二进制时保留整个字节的字符串   java AspectJ&Maven警告:“未应用……中定义的建议?”   java为什么我得到3,我不应该得到+7   java当一个方法包含多个返回的if语句时,如何从该方法中获取返回值?   在运行时循环java(scan.nextLine()!="$")   java配置休眠。cfg。春天的xml   java使用HtmlUnit模拟用户,错误   java CLI如何持续检查更改   java最大素因子(返回)