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

如何通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:57:06