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

如何使用asyncio实现后台运行的会话保活守护方法?

现有实现存在的问题
  • 事件循环提前退出:keep_alive_task协程仅创建了keep_alive后台任务就直接返回,loop.run_until_complete检测到主协程执行完毕后会直接终止事件循环,后台保活任务没有机会持续运行。
  • 同步调用阻塞事件循环:self.send基于同步requests库实现,直接在async协程中调用会阻塞整个事件循环,不仅会导致保活间隔计时不准,还会卡死后续所有异步任务的执行。
  • 事件循环获取时机错误:装饰器async_loop在函数定义阶段就调用asyncio.get_event_loop()获取事件循环,若你在非主线程实例化Session,会触发线程无默认事件循环的报错。
  • 初始化逻辑永久阻塞:__init__中直接调用被async_loop装饰的keep_alive_task,会导致Session实例化的步骤永久卡住,后续业务代码完全无法执行。
修正后的实现方案

如果必须保留requests同步调用的实现,可以通过线程池包裹同步逻辑避免阻塞事件循环,以下是可正常运行的守护保活实现:

import asyncio
import requests
import threading
from concurrent.futures import ThreadPoolExecutor

# 全局线程池用于运行同步requests请求
executor = ThreadPoolExecutor(max_workers=1)

class Session:
    def __init__(self):
        # 为每个Session创建独立的事件循环
        self.loop = asyncio.new_event_loop()
        # 保活逻辑放到守护线程运行,不阻塞初始化流程
        threading.Thread(target=self._run_keep_alive_loop, daemon=True).start()

    # 原有send逻辑不变
    def send(self, msg):
        return requests.post("你的请求地址", json=msg).json()

    # 封装同步send为异步调用,避免阻塞事件循环
    async def async_send(self, msg):
        return await self.loop.run_in_executor(executor, self.send, msg)

    async def keep_alive(self):
        while True:
            keep_alive_message = {
                "janus": "keepalive",
            }
            response = await self.async_send(keep_alive_message)
            print(response)
            await asyncio.sleep(30)

    async def keep_alive_task(self):
        asyncio.create_task(self.keep_alive())
        # 永久挂起主协程,避免事件循环提前退出
        await asyncio.Event().wait()

    def _run_keep_alive_loop(self):
        asyncio.set_event_loop(self.loop)
        self.loop.run_until_complete(self.keep_alive_task())

内容的提问来源于stack exchange,提问作者MONTASER ABDMAJID ZEHRI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 23:27:00