This commit is contained in:
parent
993113b2b7
commit
005b3f4530
13 changed files with 114 additions and 64 deletions
|
|
@ -90,8 +90,11 @@ class PortalSessionHandler(SessionHandler):
|
|||
|
||||
if session:
|
||||
# assign if we are first-connectors
|
||||
self.latest_sessid += 1
|
||||
session.sessid = self.latest_sessid
|
||||
if not session.sessid:
|
||||
# if the session already has a sessid (e.g. being inherited in the
|
||||
# case of a webclient auto-reconnect), keep it
|
||||
self.latest_sessid += 1
|
||||
session.sessid = self.latest_sessid
|
||||
session.server_connected = False
|
||||
_CONNECTION_QUEUE.appendleft(session)
|
||||
if len(_CONNECTION_QUEUE) > 1:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ _RE_SCREENREADER_REGEX = re.compile(r"%s" % settings.SCREENREADER_REGEX_STRIP, r
|
|||
_CLIENT_SESSIONS = mod_import(settings.SESSION_ENGINE).SessionStore
|
||||
|
||||
|
||||
CLOSE_NORMAL = WebSocketServerProtocol.CLOSE_STATUS_CODE_NORMAL
|
||||
|
||||
|
||||
class WebSocketClient(WebSocketServerProtocol, Session):
|
||||
"""
|
||||
Implements the server-side of the Websocket connection.
|
||||
|
|
@ -70,19 +73,21 @@ class WebSocketClient(WebSocketServerProtocol, Session):
|
|||
client_address = client_address[0] if client_address else None
|
||||
self.init_session("websocket", client_address, self.factory.sessionhandler)
|
||||
|
||||
from evennia.utils import logger
|
||||
try:
|
||||
csessid = self.http_request_uri.split("?", 1)[1]
|
||||
except Exception:
|
||||
logger.log_trace(str(self.__dict__))
|
||||
|
||||
csession = self.get_client_session()
|
||||
csession = self.get_client_session() # this sets self.csessid
|
||||
csessid = self.csessid
|
||||
uid = csession and csession.get("webclient_authenticated_uid", None)
|
||||
if uid:
|
||||
# the client session is already logged in.
|
||||
self.uid = uid
|
||||
self.logged_in = True
|
||||
|
||||
for old_session in self.sessionhandler.sessions_from_csessid(csessid):
|
||||
if (hasattr(old_session, "websocket_close_code") and
|
||||
old_session.websocket_close_code != CLOSE_NORMAL):
|
||||
# if we have old sessions with the same csession, they are remnants
|
||||
self.sessid = old_session.sessid
|
||||
self.sessionhandler.disconnect(old_session)
|
||||
|
||||
# watch for dead links
|
||||
self.transport.setTcpKeepAlive(1)
|
||||
# actually do the connection
|
||||
|
|
@ -97,11 +102,19 @@ class WebSocketClient(WebSocketServerProtocol, Session):
|
|||
reason (str or None): Motivation for the disconnection.
|
||||
|
||||
"""
|
||||
csession = self.get_client_session()
|
||||
|
||||
if csession:
|
||||
csession["webclient_authenticated_uid"] = None
|
||||
csession.save()
|
||||
self.logged_in = False
|
||||
|
||||
self.sessionhandler.disconnect(self)
|
||||
# autobahn-python: 1000 for a normal close, 3000-4999 for app. specific,
|
||||
# in case anyone wants to expose this functionality later.
|
||||
#
|
||||
# sendClose() under autobahn/websocket/interfaces.py
|
||||
self.sendClose(1000, reason)
|
||||
self.sendClose(CLOSE_NORMAL, reason)
|
||||
|
||||
def onClose(self, wasClean, code=None, reason=None):
|
||||
"""
|
||||
|
|
@ -111,19 +124,14 @@ class WebSocketClient(WebSocketServerProtocol, Session):
|
|||
|
||||
Args:
|
||||
wasClean (bool): ``True`` if the WebSocket was closed cleanly.
|
||||
reason (str): Motivation for the lost connection.
|
||||
code (int or None): Close status as sent by the WebSocket peer.
|
||||
reason (str or None): Close reason as sent by the WebSocket peer.
|
||||
|
||||
"""
|
||||
csession = self.get_client_session()
|
||||
|
||||
if csession:
|
||||
csession["webclient_authenticated_uid"] = None
|
||||
csession.save()
|
||||
self.logged_in = False
|
||||
|
||||
self.sessionhandler.disconnect(self)
|
||||
if code == CLOSE_NORMAL:
|
||||
self.disconnect(reason)
|
||||
else:
|
||||
self.websocket_close_code = code
|
||||
|
||||
def onMessage(self, payload, isBinary):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ class SessionHandler(dict):
|
|||
return newdict
|
||||
elif is_iter(data):
|
||||
return [_validate(part) for part in data]
|
||||
elif isinstance(data, (str, bytes )):
|
||||
elif isinstance(data, (str, bytes)):
|
||||
data = _utf8(data)
|
||||
|
||||
if _INLINEFUNC_ENABLED and not raw and isinstance(self, ServerSessionHandler):
|
||||
|
|
@ -257,9 +257,9 @@ class SessionHandler(dict):
|
|||
return rkwargs
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ------------------------------------------------------------
|
||||
# Server-SessionHandler class
|
||||
#------------------------------------------------------------
|
||||
# ------------------------------------------------------------
|
||||
|
||||
class ServerSessionHandler(SessionHandler):
|
||||
"""
|
||||
|
|
@ -413,7 +413,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
# set a watchdog to avoid self.disconnect from deleting
|
||||
# the session while we are looping over them
|
||||
self._disconnect_all = True
|
||||
for session in self.values:
|
||||
for session in self.values():
|
||||
session.disconnect()
|
||||
del self._disconnect_all
|
||||
|
||||
|
|
@ -443,7 +443,8 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
"""
|
||||
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=SCONN,
|
||||
protocol_path=protocol_path, config=configdict)
|
||||
protocol_path=protocol_path,
|
||||
config=configdict)
|
||||
|
||||
def portal_restart_server(self):
|
||||
"""
|
||||
|
|
@ -544,7 +545,8 @@ class ServerSessionHandler(SessionHandler):
|
|||
nsess = len(self.sessions_from_account(session.account)) - 1
|
||||
sreason = " ({})".format(reason) if reason else ""
|
||||
string = "Logged out: {account} {address} ({nsessions} sessions(s) remaining){reason}"
|
||||
string = string.format(reason=sreason, account=session.account, address=session.address, nsessions=nsess)
|
||||
string = string.format(reason=sreason, account=session.account,
|
||||
address=session.address, nsessions=nsess)
|
||||
session.log(string)
|
||||
|
||||
if nsess == 0:
|
||||
|
|
@ -670,7 +672,8 @@ class ServerSessionHandler(SessionHandler):
|
|||
amount of Sessions due to multi-playing).
|
||||
|
||||
"""
|
||||
return list(set(session.account for session in self.values() if session.logged_in and session.account))
|
||||
return list(set(session.account for session in self.values()
|
||||
if session.logged_in and session.account))
|
||||
|
||||
def session_from_sessid(self, sessid):
|
||||
"""
|
||||
|
|
@ -737,13 +740,17 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
def sessions_from_csessid(self, csessid):
|
||||
"""
|
||||
Given a cliend identification hash (for session types that offer them) return all sessions with
|
||||
a matching hash.
|
||||
Given a client identification hash (for session types that offer them)
|
||||
return all sessions with a matching hash.
|
||||
|
||||
Args
|
||||
csessid (str): The session hash
|
||||
csessid (str): The session hash.
|
||||
Returns:
|
||||
sessions (list): The sessions with matching .csessid, if any.
|
||||
|
||||
"""
|
||||
if csessid:
|
||||
return []
|
||||
return [session for session in self.values()
|
||||
if session.csessid and session.csessid == csessid]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue