0

Python 3.6 和 3.8。

我正在使用以下几行来启动服务器:

class MyServer:

    async def main(self, handler, host, port):
        self._server = await asyncio.start_server(handler, host=host, port=port)

        # Next line does not work with uvloop
        self._server._stop = False

_stop属性将被添加到处理程序中的访问。

然后在处理程序中,我会_stop像这样设置属性:

async def handler(reader, writer):
    writer._transport._server._stop = True

这在不使用 uvloop 时效果很好。但是当使用 uvloop 时,这不再有效。

当我尝试_stop在服务器对象上设置(!)属性时,我立即收到此错误:

AttributeError: 'uvloop.loop.Server' object has no attribute '_stop'

我的问题是如何在处理程序和服务器之间“通信”......?

PS。当不使用 uvloop 时,这一切都有效,因为 StreamWriter._transport 有一个属性 _server。

4

1 回答 1

0

感谢@user4815162342,我可以很容易地通过简单地传递一个成员函数作为回调来进行管理。

这不是我的第一个猜测,因为成员函数需要三个参数,而回调函数需要两个(在网上搜索“python 绑定方法”以获取更多信息以及为什么下面的代码仍然可以正常工作)。

但是下面的代码演示了它现在是如何工作的:

import asyncio


class MyServerContext:

    async def handler(self, reader, writer):
        line = await reader.readline()
        if line == b'stop\n':
            setattr(self, '_stop', True)

    async def send_stop(self):

        _, writer = await asyncio.open_connection('localhost', 6369)
        writer.write(b'stop\n')
        await writer.drain()
        writer.close()
        await writer.wait_closed()

    async def start(self):

        server = await asyncio.start_server(
            self.handler,    # <---- Member function as call back
            'localhost',
            6369)

        while not getattr(self, '_stop', False):
            await self.send_stop()

        server.close()
        await server.wait_closed()


if __name__ == '__main__':
    server_context = MyServerContext()
    asyncio.get_event_loop().run_until_complete(server_context.start())
    exit(0)

于 2021-02-05T14:24:27.450 回答