0
我一直在Python中使用asyncio.Protocol编写MUD,但我有一个问题,当用户关闭他们的客户端(通常是终端,因为你通过telnet连接),没有正确断开连接。客户端超时与asyncio.Protocol
服务器不会将用户识别为断开连接,并且它们仍保留在游戏中。
只有当客户端连接远程(出于某种原因,也许有人可以解释...)时才会出现问题,从本地主机连接时不会发生此问题。
是否有一个简洁的方式来检查用户是否仍然实际连接(没有额外的软件客户端),或者如果失败,我该如何合并超时?
我的协议看起来像这样目前:
class User(Protocol):
def connection_made(self, transport):
self.transport = transport
self.addr = transport.get_extra_info('peername')
self.authd = False
self.name = None
self.admin = False
self.room = None
self.table = None
self.db = None
self.flags = []
print("Connected: {}".format(self.addr))
server.connected.append(self)
actions['help'](self, ['welcome'])
self.get_prompt()
def data_received(self, data):
msg = data.decode().strip()
args = msg.split()
if self.authd is False:
actions['login'](self, args)
return
if msg:
if args[0] in self.db.aliases:
args[0] = str(self.db.aliases[args[0]])
msg = ' '.join(args)
args = msg.split()
if msg[0] in server.channels:
ch = db.session.query(db.models.Channel).get(msg[0])
if msg[1] =='@':
channels.send_to_channel(self, ch, msg[2:], do_emote=True)
else:
channels.send_to_channel(self, ch, msg[1:])
self.get_prompt()
return
if args[0] in actions:
if self.is_frozen():
self.send_to_self("You're frozen solid!")
else:
actions[args[0]](self, args[1:] if len(args) > 1 else None)
self.get_prompt()
return
self.send_to_self("Huh?")
else:
if self.table is not None:
actions['table'](self, None)
elif self.room is not None:
actions['look'](self, None)
def send_to_self(self, msg):
msg = "\r\n" + msg
msg = colourify(msg)
self.transport.write(msg.encode())
@staticmethod
def send_to_user(user, msg):
msg = "\r\n"+msg
msg = colourify(msg)
user.transport.write(msg.encode())
@staticmethod
def send_to_users(users, msg):
msg = "\r\n"+msg
msg = colourify(msg)
for user in users:
user.transport.write(msg.encode())
def connection_lost(self, ex):
print("Disconnected: {}".format(self.addr))
server.connected.remove(self)
if self.authd:
self.save()
server.users.remove(self)
self.room.occupants.remove(self)
注:我已经斩了很多多余的东西了。如果你想完整的代码,这是here.
似乎'asyncio.timeout'被取消 - 请参阅[Async-sig asyncio.timeout()不可移植](https://mail.python.org/pipermail/async-sig/2016-June/000033 .html)和[resurrect asyncio.timeout()上下文管理器·问题#392·python/asyncio](https://github.com/python/asyncio/issues/392) –
'asyncio.timeout'被提取到'async_timeout '图书馆。 它不适用于龙卷风,因为龙卷风与asyncio不完全兼容(有计划将其固定在龙卷风5中) –