You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MQTT消息处理函数中渲染Flask模板展示数据?

问题分析与解决方案

你的核心问题在于:handle_mytopic是MQTT的回调函数,不是Flask的HTTP请求处理函数。当MQTT收到消息时,这个函数执行并返回模板,但没有任何客户端会接收这个返回结果——HTTP是请求-响应模式,只有客户端主动发起请求,服务器才会返回内容,服务器无法主动给已打开的网页推送更新。

要实现网页实时展示MQTT数据,需要用到双向通信技术,最适合的方案是用Flask-SocketIO配合Flask-MQTT实现实时推送。


步骤1:安装依赖

先安装所需的包:

pip install flask-socketio flask-mqtt eventlet

步骤2:修改Python代码

替换原来的代码,加入SocketIO支持:

from flask import Flask, render_template
from flask_mqtt import Mqtt
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['MQTT_BROKER_URL'] = 'MY_BROKER'
app.config['MQTT_BROKER_PORT'] = 1883
app.config['MQTT_USERNAME'] = ''
app.config['MQTT_PASSWORD'] = ''
app.config['MQTT_KEEPALIVE'] = 5
app.config['MQTT_TLS_ENABLED'] = False

mqtt = Mqtt(app)
# 初始化SocketIO,允许跨域(开发环境用)
socketio = SocketIO(app, cors_allowed_origins="*")

@app.route('/')
def home():
    return render_template('home.html')

@mqtt.on_connect()
def handle_connect(client, userdata, flags, rc):
    if rc == 0:
        print('Connected successfully')
        mqtt.subscribe("iot/dht_cds")
    else:
        print('Bad connection. Code:', rc)

@mqtt.on_topic('iot/dht_cds')
def handle_mytopic(client, userdata, message):
    print('Received message on topic {}: {}'
          .format(message.topic, message.payload.decode()))
    light_value = message.payload.decode()
    # 通过SocketIO把数据推送给所有连接的客户端
    socketio.emit('update_light', {'light_value': light_value})

if __name__ == '__main__':
    print('Starting Webserver...')
    # 用socketio.run启动服务器,而非app.run
    socketio.run(app, host='0.0.0.0', debug=True)

步骤3:修改前端模板(home.html)

在模板中引入SocketIO的JS客户端,监听服务器推送的事件并更新页面:

<!DOCTYPE html>
<html>
<head>
    <title>光照数据实时展示</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
    <script type="text/javascript">
        // 连接到SocketIO服务器
        const socket = io();

        // 监听服务器发送的update_light事件
        socket.on('update_light', function(data) {
            // 更新页面上的数值显示
            document.getElementById('light-value').textContent = data.light_value;
        });
    </script>
</head>
<body>
    <h1>光照传感器数据</h1>
    <p>当前数值: <span id="light-value">等待数据...</span></p>
</body>
</html>

关键说明

  1. SocketIO的作用:打破HTTP的请求-响应限制,实现服务器主动向客户端推送数据,完美适配MQTT消息的实时展示需求。
  2. 启动方式:必须用socketio.run(app)启动服务器,因为SocketIO需要异步服务器支持,eventlet会被自动加载使用。
  3. 数据推送逻辑:当MQTT收到消息时,通过socketio.emit把数据广播给所有已连接的客户端,前端监听对应事件后更新DOM。

内容的提问来源于stack exchange,提问作者wok1909

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:30:53