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

如何使用Flask+SocketIO实现定时广播数据并支持启停控制?

使用Flask-SocketIO实现定时广播与停止功能

你原来的代码存在核心问题:time.sleep()会阻塞SocketIO的事件循环,导致整个服务响应能力下降,完全无法满足高性能要求。必须借助SocketIO自带的后台任务机制来实现,同时要为每个客户端的任务保留引用,才能支持精准停止操作。

实现思路

  • 用start_background_task()启动异步广播任务,避免阻塞主事件循环
  • 通过客户端唯一标识sid维护任务引用字典,追踪每个客户端的运行中任务
  • 收到停止指令时,通过任务引用终止对应客户端的定时广播

完整示例代码

from flask import Flask
from flask_socketio import SocketIO, emit, request
import threading

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
# 生产环境按需配置跨域,高性能场景建议用gevent/eventlet
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='gevent')

# 存储客户端任务引用:key为sid,value为任务对象
active_tasks = {}
# 共享数据锁,确保signal_list线程安全
signal_lock = threading.Lock()
signal_list = []  # 你的业务数据

@socketio.on('startPolling')
def start_polling(interval=0.5):
    sid = request.sid
    # 避免同一客户端重复启动任务
    if sid in active_tasks:
        emit('notify', {'msg': '已有广播任务在运行'})
        return

    def broadcast_loop():
        while True:
            with signal_lock:
                # 广播最新数据到当前客户端
                emit('signal_update', signal_list)
            # 用SocketIO异步睡眠,不阻塞事件循环
            socketio.sleep(interval)

    # 启动后台任务并保存引用
    task = socketio.start_background_task(broadcast_loop)
    active_tasks[sid] = task
    emit('notify', {'msg': f'广播已启动,间隔{interval}秒'})

@socketio.on('stopPolling')
def stop_polling():
    sid = request.sid
    if sid in active_tasks:
        # 终止后台任务
        active_tasks[sid].stop()
        del active_tasks[sid]
        emit('notify', {'msg': '广播已停止'})
    else:
        emit('notify', {'msg': '无运行中的广播任务'})

# 客户端断开时自动清理任务,防止内存泄漏
@socketio.on('disconnect')
def clean_task_on_disconnect():
    sid = request.sid
    if sid in active_tasks:
        active_tasks[sid].stop()
        del active_tasks[sid]

if __name__ == '__main__':
    # 生产环境建议用gevent部署,而非自带的开发服务器
    socketio.run(app, host='0.0.0.0', port=5000)

关键性能与可靠性注意事项

  • 绝对禁用time.sleep():必须使用socketio.sleep(),它是异步非阻塞的,不会影响其他客户端的请求处理
  • 线程安全处理:如果signal_list是多线程共享数据,必须加锁避免数据竞争
  • 生产环境服务器选型:务必使用gevent或eventlet作为异步服务器,Flask默认开发服务器性能极差,无法支撑高并发
  • 自动清理机制:客户端断开时主动终止任务,防止无效任务占用内存

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:55:20