Merge pull request #969 from croneter/fix-comp

Never give up trying to connect to the PMS or Alexa using websockets
This commit is contained in:
croneter 2019-09-08 15:24:01 +02:00 committed by GitHub
commit f7d8bccca3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -19,6 +19,7 @@ class WebSocket(backgroundthread.KillableThread):
def __init__(self): def __init__(self):
self.ws = None self.ws = None
self.redirect_uri = None self.redirect_uri = None
self.sleeptime = 0
super(WebSocket, self).__init__() super(WebSocket, self).__init__()
def process(self, opcode, message): def process(self, opcode, message):
@ -45,6 +46,16 @@ class WebSocket(backgroundthread.KillableThread):
def getUri(self): def getUri(self):
raise NotImplementedError raise NotImplementedError
def __sleep(self):
"""
Sleeps for 2^self.sleeptime where sleeping period will be doubled with
each unsuccessful connection attempt.
Will sleep at most 64 seconds
"""
app.APP.monitor.waitForAbort(2**self.sleeptime)
if self.sleeptime < 6:
self.sleeptime += 1
def run(self): def run(self):
LOG.info("----===## Starting %s ##===----", self.__class__.__name__) LOG.info("----===## Starting %s ##===----", self.__class__.__name__)
app.APP.register_thread(self) app.APP.register_thread(self)
@ -58,7 +69,6 @@ class WebSocket(backgroundthread.KillableThread):
LOG.info("##===---- %s Stopped ----===##", self.__class__.__name__) LOG.info("##===---- %s Stopped ----===##", self.__class__.__name__)
def _run(self): def _run(self):
counter = 0
while not self.isCanceled(): while not self.isCanceled():
# In the event the server goes offline # In the event the server goes offline
if self.isSuspended(): if self.isSuspended():
@ -68,8 +78,6 @@ class WebSocket(backgroundthread.KillableThread):
self.ws = None self.ws = None
if self.wait_while_suspended(): if self.wait_while_suspended():
# Abort was requested while waiting. We should exit # Abort was requested while waiting. We should exit
LOG.info("##===---- %s Stopped ----===##",
self.__class__.__name__)
return return
try: try:
self.process(*self.receive(self.ws)) self.process(*self.receive(self.ws))
@ -77,8 +85,8 @@ class WebSocket(backgroundthread.KillableThread):
# No worries if read timed out # No worries if read timed out
pass pass
except websocket.WebSocketConnectionClosedException: except websocket.WebSocketConnectionClosedException:
LOG.info("%s: connection closed, (re)connecting", LOG.debug("%s: connection closed, (re)connecting",
self.__class__.__name__) self.__class__.__name__)
uri, sslopt = self.getUri() uri, sslopt = self.getUri()
try: try:
# Low timeout - let's us shut this thread down! # Low timeout - let's us shut this thread down!
@ -89,41 +97,25 @@ class WebSocket(backgroundthread.KillableThread):
enable_multithread=True) enable_multithread=True)
except IOError: except IOError:
# Server is probably offline # Server is probably offline
LOG.info("%s: Error connecting", self.__class__.__name__) LOG.debug("%s: IOError connecting", self.__class__.__name__)
self.ws = None self.ws = None
counter += 1 self.__sleep()
if counter >= 10:
LOG.info('%s: Repeated IOError detected. Stopping now',
self.__class__.__name__)
break
app.APP.monitor.waitForAbort(1)
except websocket.WebSocketTimeoutException: except websocket.WebSocketTimeoutException:
LOG.info("%s: Timeout while connecting, trying again", LOG.debug("%s: WebSocketTimeoutException", self.__class__.__name__)
self.__class__.__name__)
self.ws = None self.ws = None
app.APP.monitor.waitForAbort(1) self.__sleep()
except websocket.WebsocketRedirect as e: except websocket.WebsocketRedirect as e:
LOG.info('301 redirect detected') LOG.debug('301 redirect detected: %s', e)
self.redirect_uri = e.headers.get('location', e.headers.get('Location')) self.redirect_uri = e.headers.get('location',
e.headers.get('Location'))
if self.redirect_uri: if self.redirect_uri:
self.redirect_uri.decode('utf-8') self.redirect_uri = self.redirect_uri.decode('utf-8')
counter += 1
if counter >= 10:
LOG.info('%s: Repeated WebsocketRedirect detected. Stopping now',
self.__class__.__name__)
break
except websocket.WebSocketException as e:
LOG.info('%s: WebSocketException: %s',
self.__class__.__name__, e)
if ('Handshake Status 401' in e.args or
'Handshake Status 403' in e.args):
counter += 1
if counter >= 5:
LOG.info('%s: Error in handshake detected. '
'Stopping now', self.__class__.__name__)
break
self.ws = None self.ws = None
app.APP.monitor.waitForAbort(1) self.__sleep()
except websocket.WebSocketException as e:
LOG.debug('%s: WebSocketException: %s', self.__class__.__name__, e)
self.ws = None
self.__sleep()
except Exception as e: except Exception as e:
LOG.error('%s: Unknown exception encountered when ' LOG.error('%s: Unknown exception encountered when '
'connecting: %s', self.__class__.__name__, e) 'connecting: %s', self.__class__.__name__, e)
@ -131,9 +123,9 @@ class WebSocket(backgroundthread.KillableThread):
LOG.error("%s: Traceback:\n%s", LOG.error("%s: Traceback:\n%s",
self.__class__.__name__, traceback.format_exc()) self.__class__.__name__, traceback.format_exc())
self.ws = None self.ws = None
app.APP.monitor.waitForAbort(1) self.__sleep()
else: else:
counter = 0 self.sleeptime = 0
except Exception as e: except Exception as e:
LOG.error("%s: Unknown exception encountered: %s", LOG.error("%s: Unknown exception encountered: %s",
self.__class__.__name__, e) self.__class__.__name__, e)