From: Andrew Lorimer Date: Sat, 22 May 2021 06:50:38 +0000 (+1000) Subject: clients attempt reconnection after socket close X-Git-Tag: v0.0.3~5 X-Git-Url: https://git.lorimer.id.au/ppt-control.git/diff_plain/2ab35b80cab1400bbe369006a51dd84f4c93099c clients attempt reconnection after socket close --- diff --git a/ppt_control/ppt_control_obs.py b/ppt_control/ppt_control_obs.py index aa2e44b..640d586 100755 --- a/ppt_control/ppt_control_obs.py +++ b/ppt_control/ppt_control_obs.py @@ -4,6 +4,7 @@ import obspython as obs import asyncio import websockets import threading +import logging, logging.handlers from time import sleep PORT_DEFAULT = 5678 @@ -30,12 +31,18 @@ HOTKEY_DESC_LAST = 'Last PowerPoint slide' HOTKEY_DESC_BLACK = 'Black PowerPoint slide' HOTKEY_DESC_WHITE = 'White PowerPoint slide' +LOG_LEVEL = logging.DEBUG + global cmd global attempts +global logger cmd = "" hostname = HOSTNAME_DEFAULT port = PORT_DEFAULT attempts = 0 +logger = None + +logging.basicConfig() async def communicate(): async with websockets.connect("ws://%s:%s" % (hostname, port), ping_interval=None) as websocket: @@ -48,24 +55,27 @@ async def communicate(): cmd = "" await websocket.send('{"action": "%s"}' % cmd_temp) except websockets.ConnectionClosed as exc: + logger.info("Failed to send command {}: {}".format(cmd_temp, str(exc))) + cmd = cmd_temp attempts += 1 if attempts == 4: - print("Failed to send command after {} attempts - aborting connection".format(attempts)) + logger.info("Failed to send command {} after {} attempts - aborting connection".format(cmd_temp, attempts)) attempts = 0 cmd = "" - raise websockets.exceptions.ConnectionClosedError(1006, "Sending command failed after {} attempts".format(attempts)) + break await asyncio.sleep(0.05 + 0.5*attempts**2) def run_ws(): while True: + logger.debug("Attempting to connect") try: asyncio.set_event_loop(asyncio.new_event_loop()) asyncio.get_event_loop().run_until_complete(communicate()) - except (OSError, websockets.exceptions.ConnectionClosedError): + except (OSError, websockets.exceptions.ConnectionClosedError) as e: # No server available - just keep trying pass except Exception as e: - print("Failed to connect to websocket: {} - {}".format(type(e), e)) + logger.warning("Failed to connect to websocket: {} - {}".format(type(e), e)) finally: sleep(1) @@ -79,6 +89,7 @@ def script_load(settings): global hotkey_id_last global hotkey_id_black global hotkey_id_white + global logger hotkey_id_first = register_and_load_hotkey(settings, HOTKEY_NAME_FIRST, HOTKEY_DESC_FIRST, first_slide) hotkey_id_prev = register_and_load_hotkey(settings, HOTKEY_NAME_PREV, HOTKEY_DESC_PREV, prev_slide) @@ -87,10 +98,20 @@ def script_load(settings): hotkey_id_black = register_and_load_hotkey(settings, HOTKEY_NAME_BLACK, HOTKEY_DESC_BLACK, black) hotkey_id_white = register_and_load_hotkey(settings, HOTKEY_NAME_WHITE, HOTKEY_DESC_WHITE, white) + # Set up logging + log_formatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-7.7s] %(message)s") + logger = logging.getLogger("ppt_control_obs") + logger.setLevel(LOG_LEVEL) + logger.propagate = False + console_handler = logging.StreamHandler() + console_handler.setFormatter(log_formatter) + console_handler.setLevel(LOG_LEVEL) + logger.addHandler(console_handler) + ws_daemon = threading.Thread(name="ws_daemon", target=run_ws) ws_daemon.setDaemon(True) ws_daemon.start() - print("Started websocket client") + logger.info("Started websocket client") def script_unload(): obs.obs_hotkey_unregister(first_slide) diff --git a/ppt_control/static/index.html b/ppt_control/static/index.html index b19415f..21d08af 100755 --- a/ppt_control/static/index.html +++ b/ppt_control/static/index.html @@ -38,7 +38,7 @@ Show next slide Keyboard shortcuts -

Not connected

+

Disconnected

diff --git a/ppt_control/static/ppt-control.js b/ppt_control/static/ppt-control.js index 2265ca3..f884d90 100644 --- a/ppt_control/static/ppt-control.js +++ b/ppt_control/static/ppt-control.js @@ -2,25 +2,6 @@ var DEFAULT_TITLE = "ppt-control" var preloaded = false; var preload = []; -function imageRefresh(id) { - img = document.getElementById(id); - var d = new Date; - var http = img.src; - if (http.indexOf("?t=") != -1) { http = http.split("?t=")[0]; } - img.src = http + '?t=' + d.getTime(); -} - -function startWebsocket() { - ws = new WebSocket("ws://" + window.location.host + ":5678/"); - ws.onclose = function(){ - //websocket = null; - setTimeout(function(){startWebsocket()}, 10000); - } - return ws; -} - -var websocket = startWebsocket(); - var prev = document.querySelector('#prev'), next = document.querySelector('#next'), first = document.querySelector('#first'), @@ -30,7 +11,7 @@ var prev = document.querySelector('#prev'), slide_label = document.querySelector('#slide_label'), current = document.querySelector('#current'), total = document.querySelector('#total'), - users = document.querySelector('.users'), + status_text = document.querySelector('.status_text'), current_img = document.querySelector('#current_img'), next_img = document.querySelector('#next_img'), current_div = document.querySelector('#current_div'), @@ -41,6 +22,23 @@ var prev = document.querySelector('#prev'), show_next = document.querySelector('#show_next'), shortcuts = document.querySelector('#shortcuts'); + +function startWebsocket() { + console.log("Attempting to connect") + ws = new WebSocket("ws://" + window.location.host + ":5678/"); + ws.onmessage = receive_message; + ws.onclose = function(){ + ws = null; + setTimeout(function(){websocket = startWebsocket()}, 1000); + } + if (ws.readyState !== WebSocket.OPEN) { + disconnect() + } + return ws; +} + +var websocket = startWebsocket(); + prev.onclick = function (event) { websocket.send(JSON.stringify({action: 'prev'})); } @@ -161,31 +159,25 @@ document.addEventListener('keydown', function (e) { } }); -function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - function disconnect() { - document.title = DEFAULT_TITLE; + console.log("Disconnecting") + document.title = DEFAULT_TITLE; current_img.src = "/black.jpg"; next_img.src = "/black.jpg"; - users.textContent = "Connection to PowerPoint failed"; -} - -function update_current() { + status_text.textContent = "Disconnected"; + total.textContent = "?"; + current.value = ""; } -function update_next() { -} - -websocket.onmessage = function (event) { +function receive_message(event) { data = JSON.parse(event.data); switch (data.type) { case 'state': if (data.connected == "0" || data.connected == 0) { - console.log("Disconnected"); disconnect(); break; + } else { + status_text.textContent = "Connected"; } var d = new Date; if (show_current.checked) { @@ -225,8 +217,6 @@ websocket.onmessage = function (event) { for (let i=1; i<=Number(total.textContent); i++) { image.src = "/cache/" + i + ".jpg"; preload.push(image); - console.log("Preloaded " + total.textContent); - //sleep(0.5) } preloaded = true; }