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

如何在独立线程运行asyncio/websockets服务:线程无当前事件循环报错

问题背景

需要在已运行多个工作线程、承载各类业务逻辑的小型Python桌面应用中新增WebSocket能力,响应偶发的入站WebSocket请求。因对Python异步编程不熟悉,参考相关方案均无法正常运行,Python 3.8.10环境下运行最简复现代码时抛出错误:builtins.RuntimeError: There is no current event loop in thread 'Thread-1'。

复现代码如下:

# asamp.py
import time
import datetime
import asyncio
import websockets
import threading

def bgWorker_SK():
    # 单连接处理逻辑
    async def handler(websocket, path):
        data = await websocket.recv()
        reply = f"Data recieved as:  {data}!"
        await websocket.send(reply)
        
    start_server = websockets.serve(handler, "localhost", 5564)
    asyncio.loop.run_until_complete(start_server)
    asyncio.loop.run_forever()

bgsk = threading.Thread(target=bgWorker_SK, daemon=True).start() 


if __name__ == '__main__':  
    
    # 主线程持续执行业务逻辑
    while True:        
        print (datetime.datetime.now())
        time.sleep(2)
错误原因
  • Python 3.8 版本中,子线程默认不会自动创建绑定的事件循环,直接调用asyncio.loop无法获取当前线程对应的事件循环对象,直接触发运行时错误。
  • 原代码未给运行WebSocket服务的子线程单独创建、绑定专属事件循环,是报错的核心诱因。
修复方案

不需要大规模改造原有同步业务逻辑,只需要在子线程启动异步逻辑前,手动为该线程创建并绑定独立事件循环即可,修复后可运行代码如下:

# asamp_fixed.py
import time
import datetime
import asyncio
import websockets
import threading

def bgWorker_SK():
    # 为当前子线程创建独立事件循环
    loop = asyncio.new_event_loop()
    # 将事件循环绑定到当前线程
    asyncio.set_event_loop(loop)

    # WebSocket连接处理逻辑
    async def handler(websocket, path):
        data = await websocket.recv()
        reply = f"Data recieved as:  {data}!"
        await websocket.send(reply)
        
    start_server = websockets.serve(handler, "localhost", 5564)
    # 用当前线程绑定的循环启动服务
    loop.run_until_complete(start_server)
    loop.run_forever()

# 启动后台WebSocket服务线程
threading.Thread(target=bgWorker_SK, daemon=True).start() 


if __name__ == '__main__':  
    # 主线程原有逻辑不受任何影响
    while True:        
        print (datetime.datetime.now())
        time.sleep(2)

关键说明

  • asyncio事件循环非线程安全,禁止跨线程共享同一个事件循环,每个运行异步逻辑的线程必须创建、绑定自己的独立事件循环
  • 服务启动后必须调用loop.run_forever()保证事件循环持续驻留运行,才能持续监听端口的入站WebSocket请求
  • 该方案完全不阻塞主线程的同步业务执行,适合原有同步代码占比高、不需要全量改造为异步架构的桌面应用场景
  • 验证方法:代码启动后,使用任意WebSocket客户端连接ws://localhost:5564发送测试消息,即可收到服务端响应,主线程的定时打印逻辑不会中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:27:25