[英]mqtt client does not receive message in case of thread and rest-api
I have a python script, which based on flask and mqtt.我有一个基于flask和mqtt的python脚本。 The use case is to receive a request via rest-api then to create a new thread which publishes some messages on mosquitto mqtt and expects a response (see subscribe).
用例是通过 rest-api 接收请求,然后创建一个新线程,该线程在 mosquitto mqtt 上发布一些消息并期待响应(请参阅订阅)。 My problem is that I don't receive any messages.
我的问题是我没有收到任何消息。 I think it has something to do with the thread, because without the thread it's working very fine.. Do you know what can be the problem?
我认为这与线程有关,因为没有线程它工作得很好..你知道可能是什么问题吗?
Thank you in anticipation!谢谢期待!
here the code:这里的代码:
from flask import Flask, Response
import paho.mqtt.client as mqtt
from threading import Thread
import threading
app = Flask(__name__)
lock = threading.Lock()
def on_connect(client, userdata, flags, rc): # The callback for when the client connects to the broker
print("Connected with result code {0}".format(str(rc))) # Print result of connection attempt
client.subscribe("/mytopic")
def on_message(client, userdata, msg): # The callback for when a PUBLISH message is received from the server.
print(msg.topic)
client = mqtt.Client(client_id=client_name, clean_session=True)
client.on_connect = on_connect # Define callback function for successful connection
client.on_message = on_message # Define callback function for receipt of a message
client.username_pw_set(mqtt_user, mqtt_password)
client.loop_start()
client.connect(mqtt_host)
def test(param1, param2):
lock.acquire()
try:
ret = client.publish("/mytopic", "")
while True:
check the response from mqtt => but i don't get the response anymore
....
break
finally:
lock.release()
return result
@app.route('/test/check', methods=['POST'])
def check():
global sessionId
sessionId = sessionId + 1
t = Thread(target=test, args=(sessionId,None))
t.start()
return {'id': sessionId, 'eta': 0}
if __name__ == '__main__':
app.run(debug=True)
There are a couple of problems with this.这有几个问题。
client.connect()
and the client.subscribe()
calls need iterations of the client network loop to run in order to complete properly. client.connect()
和client.subscribe()
调用都需要客户端网络循环的迭代才能运行才能正确完成。 Better to use the client.start_loop()
function to run MQTT client network loop continuously in the background on it's own.最好使用
client.start_loop()
函数自行在后台连续运行 MQTT 客户端网络循环。
You should also remove the call to client.subscribe()
that is outside the on_connect()
callback.你也应该删除调用
client.subscribe()
是外on_connect()
回调。
EDIT: As hashed out in the comments/chat the following works.编辑:正如评论/聊天中所讨论的,以下作品。 It looks like running the flask app in debug mode does some strange things and creates multiple MQTT clients over and over again with the same client id.
看起来在调试模式下运行 Flask 应用程序会做一些奇怪的事情,并使用相同的客户端 ID 一遍又一遍地创建多个 MQTT 客户端。 This leads to the broker constantly kicking the old ones off so messages never get delivered.
这导致经纪人不断地踢掉旧的,因此消息永远不会被传递。
from flask import Flask, Response
import paho.mqtt.client as mqtt
import time
from threading import Thread
import threading
app = Flask(__name__)
lock = threading.Lock()
sessionId=0
cont=True
def on_connect(client, userdata, flags, rc): # The callback for when the client connects to the broker
print("Connected with result code {0}".format(str(rc))) # Print result of connection attempt
client.subscribe("mytopic")
def on_message(client, userdata, msg): # The callback for when a PUBLISH message is received from the server.
global cont
print(msg.topic)
cont=False
client = mqtt.Client(client_id="foo", clean_session=True)
client.on_connect = on_connect # Define callback function for successful connection
client.on_message = on_message # Define callback function for receipt of a message
#client.username_pw_set(mqtt_user, mqtt_password)
client.connect("localhost", port=1884)
client.loop_start()
def test(param1, param2):
lock.acquire()
try:
ret = client.publish("mytopic", "foo")
while cont:
time.sleep(5)
print("loop")
finally:
lock.release()
result = "foo"
return result
@app.route('/test/check', methods=['POST'])
def check():
global sessionId
sessionId = sessionId + 1
t = Thread(target=test, args=(sessionId,None))
t.start()
return {'id': sessionId, 'eta': 0}
if __name__ == '__main__':
print("started")
app.run()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.