diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 0ef5c2be..d4b368e3 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -421,6 +421,8 @@ def initialize_scheduler(): schedule_job(activity_pinger.connect_server, 'Check for server response', hours=0, minutes=0, seconds=0) + schedule_job(web_socket.send_ping, 'Websocket ping', + hours=0, minutes=0, seconds=10) else: # Cancel all jobs @@ -440,6 +442,8 @@ def initialize_scheduler(): # Schedule job to reconnect server schedule_job(activity_pinger.connect_server, 'Check for server response', hours=0, minutes=0, seconds=60, args=(False,)) + schedule_job(web_socket.send_ping, 'Websocket ping', + hours=0, minutes=0, seconds=0) # Start scheduler if start_jobs and len(SCHED.get_jobs()): diff --git a/plexpy/web_socket.py b/plexpy/web_socket.py index e33dea73..3fe2f6d1 100644 --- a/plexpy/web_socket.py +++ b/plexpy/web_socket.py @@ -31,6 +31,8 @@ import logger name = 'websocket' opcode_data = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY) ws_shutdown = False +pong_timer = None +pong_count = 0 def start_thread(): @@ -58,6 +60,7 @@ def on_connect(): plexpy.PLEX_SERVER_UP = True plexpy.initialize_scheduler() + send_ping() def on_disconnect(): @@ -91,6 +94,34 @@ def close(): plexpy.WS_CONNECTED = False +def send_ping(): + if plexpy.WS_CONNECTED: + # logger.debug(u"Tautulli WebSocket :: Sending ping.") + plexpy.WEBSOCKET.ping("Hi?") + + global pong_timer + pong_timer = threading.Timer(5.0, wait_pong) + pong_timer.daemon = True + pong_timer.start() + + +def wait_pong(): + global pong_count + pong_count += 1 + + logger.warning(u"Tautulli WebSocket :: Failed to receive pong from websocket, ping attempt %s." % str(pong_count)) + + if pong_count >= plexpy.CONFIG.WEBSOCKET_CONNECTION_ATTEMPTS: + close() + + +def receive_pong(): + # logger.debug(u"Tautulli WebSocket :: Received pong.") + global pong_timer + if pong_timer: + pong_timer = pong_timer.cancel() + + def run(): from websocket import create_connection @@ -196,7 +227,10 @@ def receive(ws): ws.send_close() return frame.opcode, None elif frame.opcode == websocket.ABNF.OPCODE_PING: + # logger.debug(u"Tautulli WebSocket :: Received ping, sending pong.") ws.pong("Hi!") + elif frame.opcode == websocket.ABNF.OPCODE_PONG: + receive_pong() return None, None