如何在基于 asyncio.Protocol 的 class 中公开和使用接口方法(例如发送和接收)

How to expose and use interface methods (e.g. send and recv) in a class based on asyncio.Protocol

我已将 asyncio.Protocol 子类化以创建连接到某个服务器的 TCP 客户端。 我想将底层接口从应用程序中分离出来,并创建一个分层架构,但我不确定如何进行。

我按照TCP Echo Client present on the official documentation的例子,启动客户端的方式也很相似:

loop = asyncio.get_event_loop()
coro = loop.create_connection(partial(MyClient, loop),
                              '127.0.0.1', 8888)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()

但是,在我的协议中,我创建了两种方法(技术上是服务访问点)为 "N+1" 层提供服务:

def setDataReceivedCallback(self, fun):
    self.dataReceivedIndication = fun

def send(self, msg):
    self.transport.write(msg)

send 方法将被 N+1 层用于向服务器发送消息(请求),而 setDataReceivedCallback 将用于注册回调,当data_received 被调用(以便协议可以向 N+1 层发出一些数据已到达的指示)。

但是,我不确定如何获得这些入口点。 更清楚:

我在这里错过了什么?

瞧,答案就在文档中。 来自 Creating Connections 部分:

Note protocol_factory can be any kind of callable, not necessarily a class. For example, if you want to use a pre-created protocol instance, you can pass lambda: my_protocol.

翻译成代码的意思如下:

loop = asyncio.get_event_loop()
ThisClient = MyClient(loop)
ThisClient.setDataReceivedCallback(whateverFunction)
# And you can also use and pass around ThisClient.send at this point

coro = loop.create_connection(lambda: ThisClient,
                              '127.0.0.1', 8888)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()