-
Notifications
You must be signed in to change notification settings - Fork 720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add External Event Loop Example #72
Comments
That sounds like a reasonable request, is there anybody out there that has an example they could share? |
I got it running, but i don't think its very nice. I don't use Deferreds and I don't use select on the socket. from twisted.internet import reactor, task
def is_connected(mqttc):
if mqttc.socket() is None:
logging.error("Connection to mqtt broker lost. Stopping")
reactor.stop()
def want_write(mqttc):
if mqttc.want_write():
mqttc.loop_write()
# MQTT STUFF
mqttc = mqtt.Client(transport="websockets")
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
# Uncomment to enable debug messages
# mqttc.on_log = on_log
mqttc.connect("localhost", 1883, 60)
mqttc.subscribe("events/#", 0)
mqttc.message_callback_add('events/comp', on_component_event_message)
# mqtt event loop functions
task.LoopingCall(mqttc.loop_read).start(0.1)
task.LoopingCall(want_write, mqttc).start(0.1)
task.LoopingCall(mqttc.loop_misc).start(5)
task.LoopingCall(is_connected, mqttc).start(1)
reactor.run() |
i'am adaptive it for gevent import paho.mqtt.client as mqtt
import gevent
def handle_write(mqttc):
mqttc._sockpairR.recv(1)
status = mqttc.loop_write()
if status != mqtt.MQTT_ERR_SUCCESS:
print('error', mqtt.error_string(status))
mqttc._state = mqtt.mqtt_cs_disconnecting
def handle_read(mqttc):
status = mqttc.loop_read()
if status != mqtt.MQTT_ERR_SUCCESS:
print('error', mqtt.error_string(status))
mqttc._state = mqtt.mqtt_cs_disconnecting
def loop_forever(mqttc, idle=3):
while mqttc._state != mqtt.mqtt_cs_disconnecting:
status = mqttc.loop_misc()
if status == mqtt.MQTT_ERR_SUCCESS:
gevent.sleep(idle)
else:
print('error', mqtt.error_string(status))
mqttc._state = mqtt.mqtt_cs_disconnecting
break
# MQTT STUFF(modify it for your case)
mqttc = mqtt.Client(transport="websockets")
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
mqttc.connect("localhost", 1883, 60)
mqttc.subscribe("events/#", 0)
mqttc.message_callback_add('events/comp', on_component_event_message)
# ...
# mqtt event loop functions
loop = gevent.get_hub().loop
watcher_r = loop.io(mqttc.socket().fileno(), gevent.core.READ)
watcher_r.start(handle_read, mqttc)
watcher_w = loop.io(mqttc._sockpairR.fileno(), gevent.core.READ)
watcher_w.start(handle_write, mqttc)
# loop forever
# or gevent.spawn(loop_forever, mqttc)
loop_forever(mqttc) |
Both examples are flawed, according to https://dev.eclipse.org/mhonarc/lists/paho-dev/msg03998.html The first one will is a busy loop with a sleep. It wastes CPU time if there's nothing to do, and if there is, introduces an artificial 0.1 sec delay. From the looks of it, I think the "external event loop" support is only meant for select. Here's an example:
To support other high level event loops (twisted, gevent, asyncio, ...) https://dev.eclipse.org/mhonarc/lists/paho-dev/msg03999.html suggests to introduce another callback. I came to the same conclusion. |
Add four more callbacks and documentation to make it possible to use external event loops other than select(). This could e.g. be asyncio, twisted or gevent. * on_socket_open - called when a new socket was opened. --> watch read * on_socket_close - called when the socket is about to be closed. --> unwatch read * on_socket_register_write - called when mqtt wants to write. --> watch write * on_socket_unregister_write - called when mqtt is finished writing. --> unwatch write Add examples how to write external event loops: * loop_select.py - select() based event loop, works without the other changes. * loop_asyncio.py - asyncio based event loop, utilizes the new callbacks. This should also fix the issues eclipse#72 and eclipse#147. Signed-off-by: Jörn Heissler <eclipse.org@wulf.eu.org>
Add four more callbacks and documentation to make it possible to use external event loops other than select(). This could e.g. be asyncio, twisted or gevent. * on_socket_open - called when a new socket was opened. --> watch read * on_socket_close - called when the socket is about to be closed. --> unwatch read * on_socket_register_write - called when mqtt wants to write. --> watch write * on_socket_unregister_write - called when mqtt is finished writing. --> unwatch write Add examples how to write external event loops: * loop_select.py - select() based event loop, works without the other changes. * loop_asyncio.py - asyncio based event loop, utilizes the new callbacks. This should also fix the issues eclipse#72 and eclipse#147. Signed-off-by: Jörn Heissler <eclipse.org@wulf.eu.org>
Add four more callbacks and documentation to make it possible to use external event loops other than select(). This could e.g. be asyncio, twisted or gevent. * on_socket_open - called when a new socket was opened. --> watch read * on_socket_close - called when the socket is about to be closed. --> unwatch read * on_socket_register_write - called when mqtt wants to write. --> watch write * on_socket_unregister_write - called when mqtt is finished writing. --> unwatch write Add examples how to write external event loops: * loop_select.py - select() based event loop, works without the other changes. * loop_asyncio.py - asyncio based event loop, utilizes the new callbacks. This should also fix the issues eclipse#72 and eclipse#147. Signed-off-by: Jörn Heissler <eclipse.org@wulf.eu.org>
I think this is fixed in develop branch with the example/loop_asyncio.py. If not, feel free to reopen this issue. |
I've created asyncio-mqtt based on the mechanism described here. asyncio-mqtt attempts to wrap paho-mqtt in an idiomatic asyncio-based interface. |
I use a external loop on windows with select. The problem is that after executing client.loop_read() the socket closed and returns a -1 as file descriptor. This behaviour can be only seen on some linux distributions. |
I've had to get paho.mqtt to coexist (not necessarily fully integrate) with an existing twisted reactor. I found that none of the examples really showed what I wanted to do. I've put together a small example of how to wrap paho,mqtt as a twisted service, available in this gist. |
Hi,
i'd like to use this library together with the twisted reactor. Since i'm new to both paho.mqtt and twisted its hard for me to figure this one out. It would be nice to have an example of the external event loop usage (mustn't be twisted).
The text was updated successfully, but these errors were encountered: