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

python-socketio AsyncServer异步emit随机延迟问题求助

问题分析与解决方案

你的核心问题出在同步回调中使用asyncio.run()调用sio.emit(),这会破坏python-socketio AsyncServer的事件循环一致性,导致消息延迟和任务重复执行。

问题根源

  1. asyncio.run()会创建一个全新的独立事件循环,和socketio AsyncServer运行的主事件循环完全分离。emit的消息会在这个临时循环中排队,无法及时被socketio的通信逻辑处理,因此出现随机延迟。
  2. 每次调用asyncio.run()都会启动、销毁一次事件循环,这个过程会触发之前未完成的任务重复执行,导致多次调用时除最后一个外的任务都被重复执行。

修复方案

必须让sio.emit()在socketio绑定的主事件循环中执行,不能用asyncio.run()创建新循环。根据get_some_status的执行线程,分两种情况处理:

情况1:get_some_status在当前异步线程执行(同步调用后立即触发回调)

直接在同步回调中用主循环创建异步任务:

import asyncio
import socketio
from aiohttp import web

async def emit_status(cb):
    print("Returning status: ", repr(cb))
    await sio.emit('status', repr(cb))

@sio.on('message')
async def get_status(sid, message):
    # 用同步回调包装异步emit逻辑
    def callback_status(cb):
        asyncio.create_task(emit_status(cb))
    get_some_status(callback_status)

sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)

if __name__ == '__main__':
    web.run_app(app, host='0.0.0.0')

情况2:get_some_status在其他线程执行(回调跨线程触发)

需要用线程安全的方式调度主循环执行emit任务:

import asyncio
import socketio
from aiohttp import web

# 保存主事件循环
main_loop = None

async def emit_status(cb):
    print("Returning status: ", repr(cb))
    await sio.emit('status', repr(cb))

def callback_status(cb):
    # 线程安全地向主循环提交任务
    main_loop.call_soon_threadsafe(asyncio.create_task, emit_status(cb))

@sio.on('message')
async def get_status(sid, message):
    get_some_status(callback_status)

sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)

if __name__ == '__main__':
    global main_loop
    main_loop = asyncio.get_event_loop()
    web.run_app(app, host='0.0.0.0')

关键说明

  • 始终让socketio的异步操作(如emit、send)在它绑定的主事件循环中执行,避免创建独立循环。
  • 跨线程调用异步逻辑时,必须使用call_soon_threadsafe保证线程安全,否则会导致循环崩溃或数据竞争。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:25:23