hbmqtt
hbmqtt copied to clipboard
How to know if client is connected?
I'm using hbmqtt v0.9.0. My program, as an MQTT client, sometimes gets "Disconnected from broker" log and no longer receive new data from Mosquitto broker. I'm using default config (with auto-reconnect).
I have questions:
- Does "auto-reconnect" work when connection is lost, while waiting for message in
deliver_message()
? - Any way to check if client is connected, so that I can call
reconnect()
and subscribe again?
Log: https://paste.ee/p/VVAV0
use MQTTClient(config={"auto_reconnect":True})
@luchermans Please read my question carefully. I wrote:
I'm using default config (with auto-reconnect).
Sorry did not look carefully. I have a related issue using python and MQTTClient gives "Disconnected from broker" (simulate by restarting the hbmqtt broker) "auto_reconnect" seems to do reconnect but not re-subscribe.
I have solved the issue by MQTTClient(config={'auto_reconnect':False})
then a Connection lost / Disconnected throws an error so I can handle the re-connect myself.
@luchermans Thank you. I will try that option. My case also seems to be "not re-subscribed".
class MockedMQTTClient(MQTTClient):
@asyncio.coroutine
def handle_connection_close(self):
def cancel_tasks():
self._no_more_connections.set()
while self.client_tasks:
task = self.client_tasks.popleft()
if not task.done():
task.set_exception(ClientException("Connection lost"))
self.logger.debug("Watch broker disconnection")
# Wait for disconnection from broker (like connection lost)
yield from self._handler.wait_disconnect()
self.logger.warning("Disconnected from broker")
# Block client API
self._connected_state.clear()
# stop an clean handler
#yield from self._handler.stop()
self._handler.detach()
self.session.transitions.disconnect()
if hasattr(self, 'on_connection_close'):
if inspect.iscoroutinefunction(self.on_connection_close):
yield from self.on_connection_close()
else:
self.on_connection_close()
if self.config.get('auto_reconnect', False):
# Try reconnection
self.logger.debug("Auto-reconnecting")
try:
yield from self.reconnect()
except ConnectException:
# Cancel client pending tasks
cancel_tasks()
else:
# Cancel client pending tasks
cancel_tasks()
def set_close_callback(self, callback):
self.on_connection_close = callback
Have done for myself in this dirty way.
If some kind of callback`s applicable for current project. I'm glad to prepare PR
@stas-dubrovskyi: Nice - but hbmqtt should really supply a means of setting on_connect / on_message callbacks, as paho does. It's not difficult - shame the pkg is neglected as there is call for it ...
Yeah, looks like the only way is to not use the broken reconnect functionality:
async def process_messages(self):
while True:
try:
await self._cli.reconnect()
await self._cli.subscribe([...])
while True:
msg: hbmqtt.session.ApplicationMessage = await self._cli.deliver_message()
if not msg:
logger.warning("No message. Disconnected?")
raise RuntimeError('Disconnected?')
do_stuff(msg)
except KeyboardInterrupt:
raise
except:
logger.exception("whoops")
await asyncio.sleep(5)
dirty but works