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

RestAPI与WebSockets结合:同时实现传统请求响应与实时数据获取

实现Flask传统API与实时数据推送共存的方案

可以用Flask-SocketIO扩展来实现,它能让你的Flask应用同时处理HTTP请求(传统REST API)和WebSocket连接(实时数据推送),完全符合你的需求。以下是具体实现步骤:

1. 安装必要依赖

后端需要安装Flask-SocketIO:

pip install flask-socketio python-socketio

前端React需要安装socket.io客户端:

npm install socket.io-client

2. 修改Flask后端代码

保留原有的REST API接口,同时添加WebSocket相关逻辑,优化Tuya API连接复用(避免每次请求重新初始化连接):

from flask import Flask, request
from flask_cors import CORS
from flask_socketio import SocketIO, emit
from tuya_connector import TuyaOpenAPI, TUYA_LOGGER
import time
from threading import Thread

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})  # 配置跨域支持WebSocket
socketio = SocketIO(app, cors_allowed_origins="*")

# 全局初始化Tuya OpenAPI连接,避免每次请求重复初始化
ACCESS_ID = ""
ACCESS_KEY = ""
API_ENDPOINT = ""
openapi = TuyaOpenAPI(API_ENDPOINT, ACCESS_ID, ACCESS_KEY)
openapi.connect()

# 保留原有的传统REST API接口
@app.get("/api/device/<string:deviceid>")
def getdata(deviceid):
    # 调用Tuya API获取设备信息
    response = openapi.get("/v1.0/devices/{}".format(deviceid))
    return response

# WebSocket连接事件
@socketio.on('connect')
def handle_connect():
    print('客户端已连接')
    emit('connected', {'message': 'WebSocket连接成功'})

# 客户端订阅特定设备的实时数据
@socketio.on('subscribe_device')
def handle_subscribe(deviceid):
    def push_realtime_data():
        while True:
            # 定时获取设备数据并推送给客户端
            try:
                response = openapi.get("/v1.0/devices/{}".format(deviceid))
                emit('device_realtime_data', {'deviceid': deviceid, 'data': response})
            except Exception as e:
                emit('error', {'message': str(e)})
            time.sleep(5)  # 每5秒推送一次,可根据需求调整间隔
    
    # 启动线程持续推送数据
    Thread(target=push_realtime_data, daemon=True).start()

if __name__ == '__main__':
    socketio.run(app, debug=True)

3. React前端实现

同时保留HTTP请求调用传统API,以及WebSocket接收实时数据:

import { useEffect, useState } from 'react';
import io from 'socket.io-client';

const DevicePage = ({ deviceId }) => {
    const [staticData, setStaticData] = useState(null);
    const [realtimeData, setRealtimeData] = useState(null);
    const socket = io('http://localhost:5000');  // 替换为你的Flask服务地址

    // 调用传统REST API获取静态数据
    useEffect(() => {
        const fetchStaticData = async () => {
            const res = await fetch(`http://localhost:5000/api/device/${deviceId}`);
            const data = await res.json();
            setStaticData(data);
        };
        fetchStaticData();
    }, [deviceId]);

    // 处理WebSocket实时数据
    useEffect(() => {
        // 监听连接成功事件
        socket.on('connected', (msg) => {
            console.log(msg.message);
            // 订阅当前设备的实时数据
            socket.emit('subscribe_device', deviceId);
        });

        // 接收实时设备数据
        socket.on('device_realtime_data', (data) => {
            setRealtimeData(data.data);
        });

        // 监听错误信息
        socket.on('error', (err) => {
            console.error('实时数据推送错误:', err.message);
        });

        // 组件卸载时断开连接
        return () => {
            socket.disconnect();
        };
    }, [deviceId, socket]);

    return (
        <div>
            <h2>设备静态信息</h2>
            <pre>{JSON.stringify(staticData, null, 2)}</pre>
            <h2>设备实时数据</h2>
            <pre>{JSON.stringify(realtimeData, null, 2)}</pre>
        </div>
    );
};

export default DevicePage;

关键说明

  • 连接复用:将Tuya OpenAPI的初始化移到全局,避免每次HTTP请求或WebSocket推送都重新建立连接,提升性能。
  • 线程处理:WebSocket推送实时数据时使用守护线程,避免阻塞Flask的事件循环。
  • 跨域配置:确保Flask的CORS和SocketIO的跨域配置正确,避免前端连接失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:05:46