如何通过Flask从TCP Socket读取数据并在网页中持续更新数值
问题分析
你当前的代码实现了从TCP Socket获取传感器数据并通过Flask渲染模板,但网页无法自动更新数据——因为Jinja2模板是在服务器端一次性渲染后发送给浏览器,页面加载完成后不会主动同步后端的data变化。要实现实时更新,需要引入双向实时通信机制,最适合的方案是使用Flask-SocketIO。
解决方案步骤
1. 安装依赖
首先安装Flask-SocketIO库:
pip install flask-socketio
2. 修改后端Python代码
调整代码,集成SocketIO实现实时数据推送,同时优化数据解析和异常处理:
from flask import Flask, render_template from flask_socketio import SocketIO import threading import socket import time from threading import Lock app = Flask(__name__) # 配置SocketIO,允许跨域,开启异步模式 app.config['SECRET_KEY'] = 'your-secret-key' socketio = SocketIO(app, cors_allowed_origins="*") # 线程锁保证数据更新的线程安全 data_lock = Lock() sensor_data = {'Temperature': '0.0', 'Humidity': '0.0'} @app.route('/sensor_data') def index(): return render_template('sensor_data.html', data=sensor_data) def update_data(): global sensor_data sock = None while True: try: # 尝试建立TCP连接(断开后自动重连) if not sock or sock._closed: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('192.168.56.1', 35000)) print("TCP连接已建立") # 发送请求并接收数据 sock.send('A\n'.encode()) raw_data = sock.recv(1024).decode().strip() # 安全解析数据(避免切片越界) new_data = {} if len(raw_data) >= 57: new_data['Temperature'] = raw_data[33:38].strip() new_data['Humidity'] = raw_data[52:57].strip() # 线程安全更新全局数据,并推送给前端 with data_lock: sensor_data.update(new_data) socketio.emit('sensor_update', sensor_data) print(f"已推送数据: {sensor_data}") time.sleep(1) except Exception as e: print(f"TCP异常: {e}") # 连接断开后等待3秒重连 if sock: sock.close() time.sleep(3) if __name__ == '__main__': # 启动数据更新线程 threading.Thread(target=update_data, daemon=True).start() # 启动SocketIO服务 socketio.run(app, debug=True, host='0.0.0.0')
3. 修改前端HTML页面
添加SocketIO客户端监听,实现页面数据自动更新:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>实时传感器数据</title> <!-- 引入SocketIO客户端库(可本地下载后引入,避免CDN依赖) --> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script> </head> <body> <h1>实时传感器数据</h1> <p>Temperature: <span id="temperature">{{ data.Temperature }}</span> °C</p> <p>Humidity: <span id="humidity">{{ data.Humidity }}</span> %H</p> <script> // 连接到SocketIO服务器 const socket = io(); // 监听服务器推送的传感器数据更新 socket.on('sensor_update', function(data) { // 更新页面元素内容 document.getElementById('temperature').textContent = data.Temperature; document.getElementById('humidity').textContent = data.Humidity; }); </script> </body> </html>
关键优化点说明
- 实时通信:通过SocketIO实现服务器主动向前端推送数据,替代传统轮询方案,效率更高。
- 线程安全:使用
threading.Lock保证多线程下数据更新的安全性。 - 异常处理:TCP连接断开后自动重连,避免程序崩溃;数据解析时增加长度判断,防止切片越界报错。
- 初始数据渲染:页面加载时仍通过Jinja2渲染初始数据,保证首次加载有内容。
内容的提问来源于stack exchange,提问作者HariKrishna
相关产品推荐
相关产品推荐

