与SocketIO一起使用时,永远不会调用\u connect上的Flask MQTT

与SocketIO一起使用时,永远不会调用\u connect上的Flask MQTT,flask,socket.io,mqtt,Flask,Socket.io,Mqtt,我正在尝试在 在上面的示例中,订阅MQTT主题是由套接字客户端触发的。但我希望我的MQTT通道保持通信,即使没有套接字客户端 所以我尝试订阅@mqtt.on_connect()事件。但这个回调永远不会被调用。 但一旦使用套接字启动订阅,MQTT消息就开始正常地流动 我已经在不涉及web套接字的情况下实现了Flask MQTT应用程序,它们工作得很好。SocketIO是否以某种方式干扰MQTT生命周期事件 以下是最低限度的代码: # Flask MQTT Web socket bridge

我正在尝试在

在上面的示例中,订阅MQTT主题是由套接字客户端触发的。但我希望我的MQTT通道保持通信,即使没有套接字客户端

所以我尝试订阅@mqtt.on_connect()事件。但这个回调永远不会被调用。 但一旦使用套接字启动订阅,MQTT消息就开始正常地流动

我已经在不涉及web套接字的情况下实现了Flask MQTT应用程序,它们工作得很好。SocketIO是否以某种方式干扰MQTT生命周期事件

以下是最低限度的代码:

# Flask MQTT Web socket bridge
 
from flask_mqtt import Mqtt
from flask import Flask, render_template 
from flask_socketio import SocketIO, emit
 
app = Flask(__name__)
app.config['SECRET'] = 'my-secret'
app.config['MQTT_BROKER_URL'] = 'localhost'      
app.config['MQTT_BROKER_PORT'] = 1883
app.config['MQTT_TLS_ENABLED'] = False  
app.config['TEMPLATES_AUTO_RELOAD'] = True

mqtt = Mqtt(app)
socketio = SocketIO (app, async_mode='gevent', cors_allowed_origins="*")  

@app.route('/')
def index():
    return render_template('index.html')
    
@socketio.on('connect')
def on_socket_connect ():
    print ('Connected to socket client.')
    mqtt.subscribe('mytopic')  
    
# This is never called:
@mqtt.on_connect()  
def on_mqtt_connect (client, userdata, flags, rc):
    print ('Connected to MQTT broker.')
    #mqtt.subscribe ('mytopic')   # this would be ideal
    
@mqtt.on_message()
def on_message(client, userdata, message):
    socketio.send (message.payload.decode())

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000, use_reloader=False, debug=True)

@NagaRajS,我得出的结论是,目前不可能在Flask中实现MQTT onConnect回调工作。这是我不使用Flask MQTT的解决方案的概要:

# Flask socketIO server with classical Paho MQTT  
# Unlike the Flask-MQTT version, this correctly calls MQTT on_connect()

from flask import Flask, render_template
import paho.mqtt.client as mqtt
from flask_socketio import SocketIO

sub_topic = 'my/sub/topic'
pub_topic = 'my/pub/topic'
server = 'localhost'
MQTTport = 1883
client = None

app = Flask(__name__)
socketio = SocketIO (app, async_mode='gevent', cors_allowed_origins="*") 

# SocketIO

@socketio.on('connect')
def on_connect ():
    print ('Socket client connected.')
    socketio.send ('Socket server ready.')

@socketio.on ('message')    
def on_publish (payload):
    client.publish (pub_topic, payload)
    
# MQTT
   
def on_connect (client, userdata, flags, rc):
    print('* Connected to MQTT broker *')
    client.subscribe (sub_topic, qos=0)  
    client.publish (pub_topic, 'MQTT server ready.')

def on_message (client, userdata, msg):
    socketio.send (msg.payload.decode())

# HTTP

@app.route('/')
def index():
    return render_template('bridge.html')
    
# Main  
  
client = mqtt.Client("Mqtt-socket-bridge-2021", clean_session=True)   
client.on_connect = on_connect
client.on_message = on_message
client.connect(server, MQTTport, keepalive=60)

print ('Starting the MQ loop..')
client.loop_start()   

print ('Starting the socket server on port 5000...')    
socketio.run (app, host='0.0.0.0', port=5000, use_reloader=False, debug=True)
bridge.html:

<!DOCTYPE html>
<html>
<head>
    <title>MQTT WebSock bridge</title>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.0/socket.io.min.js"></script>
    <script type="text/javascript">
     var socket = io.connect('http://localhost:5000');

     socket.on('connect', function()
     {
        console.log ("Connected to socket server.");
     });

     socket.on('message', function(msg)
     {  
        console.log (msg);
        socket.send ('Received: '+msg)
     });
 </script>
</body>
</html>

MQTT韦氏桥
var socket=io.connect('http://localhost:5000');
socket.on('connect',function()
{
console.log(“连接到套接字服务器”);
});
socket.on('message',函数(msg)
{  
console.log(msg);
socket.send('Received:'+msg)
});

@NagaRajS,我得出的结论是,目前不可能在Flask中实现MQTT onConnect回调。这是我不使用Flask MQTT的解决方案的概要:

# Flask socketIO server with classical Paho MQTT  
# Unlike the Flask-MQTT version, this correctly calls MQTT on_connect()

from flask import Flask, render_template
import paho.mqtt.client as mqtt
from flask_socketio import SocketIO

sub_topic = 'my/sub/topic'
pub_topic = 'my/pub/topic'
server = 'localhost'
MQTTport = 1883
client = None

app = Flask(__name__)
socketio = SocketIO (app, async_mode='gevent', cors_allowed_origins="*") 

# SocketIO

@socketio.on('connect')
def on_connect ():
    print ('Socket client connected.')
    socketio.send ('Socket server ready.')

@socketio.on ('message')    
def on_publish (payload):
    client.publish (pub_topic, payload)
    
# MQTT
   
def on_connect (client, userdata, flags, rc):
    print('* Connected to MQTT broker *')
    client.subscribe (sub_topic, qos=0)  
    client.publish (pub_topic, 'MQTT server ready.')

def on_message (client, userdata, msg):
    socketio.send (msg.payload.decode())

# HTTP

@app.route('/')
def index():
    return render_template('bridge.html')
    
# Main  
  
client = mqtt.Client("Mqtt-socket-bridge-2021", clean_session=True)   
client.on_connect = on_connect
client.on_message = on_message
client.connect(server, MQTTport, keepalive=60)

print ('Starting the MQ loop..')
client.loop_start()   

print ('Starting the socket server on port 5000...')    
socketio.run (app, host='0.0.0.0', port=5000, use_reloader=False, debug=True)
bridge.html:

<!DOCTYPE html>
<html>
<head>
    <title>MQTT WebSock bridge</title>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.0/socket.io.min.js"></script>
    <script type="text/javascript">
     var socket = io.connect('http://localhost:5000');

     socket.on('connect', function()
     {
        console.log ("Connected to socket server.");
     });

     socket.on('message', function(msg)
     {  
        console.log (msg);
        socket.send ('Received: '+msg)
     });
 </script>
</body>
</html>

MQTT韦氏桥
var socket=io.connect('http://localhost:5000');
socket.on('connect',function()
{
console.log(“连接到套接字服务器”);
});
socket.on('message',函数(msg)
{  
console.log(msg);
socket.send('Received:'+msg)
});

您只是在为Flask/HTTP部分使用内置Web服务器吗?如果您使用的是uwsgi,我想知道它是否与@Dan类似,我使用的是gevent服务器。普通烧瓶app.run()不是我的选项,因为我认为主循环必须在SocketIO的控制下。顺便说一句,我找到了一个解决问题的方法,下面是你共享的链接。我消除了Flask MQTT,现在我直接使用paho MQTT库。在运行应用程序循环之前,我启动自己的MQTT循环。这很好,也就是说,我现在得到了on_connect()回调。@Raja,我能得到源代码吗。。我也尝试过这个解决方案。mqtt连接,但当我尝试连接本地MOSQUITO服务器时,会无限期地调用on_connect函数。您是否只是将内置Web服务器用于Flask/HTTP部分?如果您使用的是uwsgi,我想知道它是否与@Dan类似,我使用的是gevent服务器。普通烧瓶app.run()不是我的选项,因为我认为主循环必须在SocketIO的控制下。顺便说一句,我找到了一个解决问题的方法,下面是你共享的链接。我消除了Flask MQTT,现在我直接使用paho MQTT库。在运行应用程序循环之前,我启动自己的MQTT循环。这很好,也就是说,我现在得到了on_connect()回调。@Raja,我能得到源代码吗。。我也尝试过这个解决方案。mqtt连接,但当我尝试连接本地MOSQUITO服务器时,会无限期地调用on_connect函数。