python asyncio中协议工厂的要求是什么?

时间:2016-09-14 15:29:09

标签: python python-3.5 python-asyncio

我正在查看UDP echo server

的示例
import asyncio

class EchoServerProtocol:
    def connection_made(self, transport):
        self.transport = transport

    def datagram_received(self, data, addr):
        message = data.decode()
        print('Received %r from %s' % (message, addr))
        print('Send %r to %s' % (message, addr))
        self.transport.sendto(data, addr)

loop = asyncio.get_event_loop()
print("Starting UDP server")
# One protocol instance will be created to serve all client requests
listen = loop.create_datagram_endpoint(
    EchoServerProtocol, local_addr=('127.0.0.1', 9999))
transport, protocol = loop.run_until_complete(listen)

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

transport.close()
loop.close()

似乎是电话......

loop.create_datagram_endpoint(EchoServerProtocol, local_addr=('127.0.0.1', 9999))

......正在做这里的所有工作。 method documentation为第一个参数(protocol_factory)声明了以下内容:

  

protocol_factory必须是可调用的,返回协议实例。

我的问题:

  • 什么定义了protocol instance
  • returning a protocol instance {/ 1}}的{​​{1}}措辞是否有所不同?
  • 示例中的initiating a protocol object如何满足此要求?

1 个答案:

答案 0 :(得分:3)

什么定义协议实例

协议是您定义的类,它实现Protocols section中定义的接口之一,即提供一组回调的实现,例如: Connection Callbacks

因此,对于您发布的UDP echo服务器示例,EchoServerProtocol用户定义的类实际上通过实现connection_madedatagram_received来定义协议。

总之,如果你在一个类中实现其中一个回调,你就会被定义为Protocol。因此,该类的实例/对象将是协议实例

是否为启动协议对象返回协议实例不同的措辞?

正式。在您返回协议实例之前,您将初始化。所以基本上一个是另一个的先决条件。

示例中的EchoServerProtocol如何满足此要求?

首先,正如第一个问题的回答,EchoServerProtocol定义了一个协议。因此,下一步是提供protocol_factorydefined为:

  

protocol_factory必须是可调用的,返回协议实例。

所以为了满足这个要求,你可以使用这个简单的方法:

def my_protocol_factory():
    return EchoServerProtocol()

请注意,此工厂首先初始化协议实例,然后返回它。

因此,在示例中可能会让您感到困惑的是,类EchoServerProtocol本身作为protocol_factory传递,但如果您总结我所说的内容,您会看到{ {1}}实际上是一个可调用的,当它被调用时,即EchoServerProtocol它实际上初始化了一个EchoServerProtocol()实例,并将其返回。

所以,这个例子符合要求。