异步协议的三重实现

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关闭应用程序按钮Listener   Java中的多线程同步在Java示例中的思考   java如何查看Tomcat正在使用/访问的JAR?   java My代码在调用垃圾收集器后不会终止   多线程Java连接线程池和connectionfactory?   java在运行时修改JAR文件   java Android:使用光标时引发IllegaleException   在Netbeans中测试不可执行库的java?   泛型在参数上强制子类Java类型   spring Java:继承与依赖注入“自动连线”   javascript如何解析这个xml元素   java打印特定序列中的数组   带有ProcessingTimeSessionWindow的java Apache Flink自定义触发器   java如何配置消息驱动的Bean应用程序和Glassfish来使用来自远程MessageBroker的消息?