python - 连接丢失后如何销毁异步服务器上的协议实例?
问题描述
我在 Python 3.7 上有异步服务器。对于每个连接,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
import asyncio
class EchoClientProtocol(asyncio.Protocol):
def __init__(self, message, on_con_lost, loop):
self.message = message
self.loop = loop
self.on_con_lost = on_con_lost
def connection_made(self, transport):
transport.write(self.message.encode())
print('Data sent: {!r}'.format(self.message))
def data_received(self, data):
print('Data received: {!r}'.format(data.decode()))
def connection_lost(self, exc):
print('The server closed the connection')
self.on_con_lost.set_result(True)
async def main():
# Get a reference to the event loop as we plan to use
# low-level APIs.
loop = asyncio.get_running_loop()
on_con_lost = loop.create_future()
message = 'Hello World!'
transport, protocol = await loop.create_connection(
lambda: EchoClientProtocol(message, on_con_lost, loop),
'127.0.0.1', 8888)
# Wait until the protocol signals that the connection
# is lost and close the transport.
try:
await on_con_lost
finally:
transport.close()
输出:
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
解决方案
user4815162342 是对的。感谢您的回复。我的愚蠢错误。
如果你想有一个监控任务,你应该让它成为一个协程,并在连接丢失时取消它。例如:
至于 check_connection 方法,我只是更改了代码并添加了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")
推荐阅读
- tags - 开始和结束标签在乳胶中
- python - Odoo 10:如何在联系表单视图中制作单独的地址行?
- html - 溢出列
- javascript - 使用 Cordova Hybrid 应用程序将文件复制到路径
- c# - 为大型 xml 文件选择单节点方法
- php - 在新的虚拟主机上出现此错误未定义的偏移量:1 和 2
- angular - Angular 6服务器端渲染(SSR)从组件设置状态代码
- java - 如何在 MongoDB 中聚合来自多个集合的查询结果?
- javascript - 使用 Webpack 4 减少和优化具有两个入口点的捆绑包
- assembly - 我对 A20 线路校验码的理解是否正确?