diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6dca910..b483d3c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,12 @@ Unreleased **Fixed** +* Fixed reconnection on the Twisted transport failing after a connection had + been idle for more than a few seconds: ``connect`` now schedules the + connection through the reactor thread so an idle reactor is woken to service + it (previously the new connector was added from another thread and the + reactor, blocked in ``select()``, never noticed it). + **Deprecated** **Removed** diff --git a/src/roslibpy/comm/comm_autobahn.py b/src/roslibpy/comm/comm_autobahn.py index 3a830fd..bbf6cc0 100644 --- a/src/roslibpy/comm/comm_autobahn.py +++ b/src/roslibpy/comm/comm_autobahn.py @@ -71,6 +71,16 @@ def __init__(self, *args, **kwargs): def connect(self): """Establish WebSocket connection to the ROS server defined for this factory.""" + # Route the connection setup through the reactor thread. Calling + # ``connectWS`` directly only happens to work while the reactor is busy; + # once it is idle (e.g. more than ``closeHandshakeTimeout`` seconds after + # a previous disconnect) it sits blocked in ``select()`` and never + # notices a connector added from another thread, so the connection times + # out. ``callFromThread`` wakes it, and is also safe before the reactor + # has started (the call is queued and runs once it does). + reactor.callFromThread(self._connect) + + def _connect(self): self.connector = connectWS(self) @property