From 47d3aa6c79dc277666b33c66ea12a611994a85f4 Mon Sep 17 00:00:00 2001 From: ejel Date: Thu, 21 Jun 2018 22:29:27 -0700 Subject: [PATCH] Fix #61 freeze/broken pipe after some idle time When keeping long-lived websocket connection, after some idle time the connection will go into a bad state. Calling send() cause no response at first and then broken pipe error is raised on the subsequent call. The cause is that there is no designated thread to keep the socket alive. --- samsungctl/remote_websocket.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/samsungctl/remote_websocket.py b/samsungctl/remote_websocket.py index f3062d9..49370ff 100644 --- a/samsungctl/remote_websocket.py +++ b/samsungctl/remote_websocket.py @@ -1,8 +1,9 @@ import base64 import json import logging -import socket +import threading import time +import select from . import exceptions @@ -26,9 +27,12 @@ def __init__(self, config): self._serialize_string(config["name"])) self.connection = websocket.create_connection(url, config["timeout"]) - self._read_response() + ## Keep long-lived connection alive by spawning a thread + thread = threading.Thread(target=self._keep_alive, daemon=True) + thread.start() + def __enter__(self): return self @@ -73,6 +77,18 @@ def _read_response(self): logging.debug("Access granted.") + def _keep_alive(self): + while True: + r, w, e = select.select((self.connection.sock, ), (), ()) + if not (self.connection and self.connection.connected): + # stop if connection was already closed + # while blocking in select function above + logging.debug("keep alive thread terminating.") + return + if r: + _ = self.connection.recv() + logging.debug("data received.") + @staticmethod def _serialize_string(string): if isinstance(string, str):