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中) –