连接丢失后如何销毁异步服务器上的协议实例?

2024-09-27 21:25:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有python3.7上的asynsio服务器。 对于每个连接,asyncio都会创建一个new EchoServerProtocol()对象。在接收到第一个数据包后,服务器关闭连接,但EchoServerProtocol()对象仍保留在内存中。你能告诉我如何正确地把它取下来吗?我知道在asyncio的某个地方有指向它的链接。在

服务器.py

import asyncio

class EchoServerProtocol(asyncio.Protocol):

    def __init__(self):
        self.__loop = asyncio.get_event_loop()

    def connection_made(self, transport):
        self.__loop.call_later(5, self.check_connection)
        print('Connection made')
        self.transport = transport

    def connection_lost(self, exc):
        print('Connection lost')

    def data_received(self, data):
        message = data.decode()
        print('Data received: {!r}'.format(message))

        print('Send: {!r}'.format(message))
        self.transport.write(data)

        print('Close the client socket')
        self.transport.close()

    def check_connection(self):
        print('check connection here')
        self.__loop.call_later(5, self.check_connection)

async def main():
    loop = asyncio.get_running_loop()

    server = await loop.create_server(
        lambda: EchoServerProtocol(),
        '127.0.0.1', 8888)

    async with server:
        await server.serve_forever()


asyncio.run(main())

客户端.py

^{2}$

输出:

Connection made
Data received: 'Hello World!'
Send: 'Hello World!'
Close the client socket
Connection lost
check connection here
check connection here
check connection here
check connection here
check connection here
check connection here
check connection here
check connection here

Tags: self服务器loopasynciodatahereserverdef
2条回答

After receiving the first packet, the server closes the connection, but the EchoServerProtocol() object remains in memory.

看看你的代码,是check_connection将对象保存在内存中。具体来说,check_connection的结尾说:

        self.__loop.call_later(5, self.check_connection)

这意味着:“5秒后,在self上调用check_connection”。事实上,self是一个不再使用的协议,这并不重要-事件循环被告知在5秒后调用一个函数,它将完全这样做。在

如果你想有一个监视任务,你应该把它设为一个协程,当连接丢失时,取消。例如:

^{pr2}$

用户4815162342是正确的。谢谢你的答复。我愚蠢的错误。在

If you want to have a monitoring task, you should make it a coroutine and cancel it when >the connection is lost. For example:

至于check_连接方法,我只是更改了代码并添加了del处理程序,以确保对象被删除。在

def check_connection(self):
    print('check connection here')
    if not self.transport.is_closing():
        self.__loop.call_later(5, self.check_connection)

def __del__(self):
    print("destroy protocol")

相关问题 更多 >

    热门问题