0

0

如何同时运行 aiogram 3 机器人与 aiohttp Web 服务

花韻仙語

花韻仙語

发布时间:2025-12-29 15:28:02

|

998人浏览过

|

来源于php中文网

原创

如何同时运行 aiogram 3 机器人与 aiohttp Web 服务

本文介绍在单进程内并行启动 aiogram 3 轮询模式机器人和 aiohttp 异步 web 服务器的正确方法,避免事件循环冲突,并提供可维护、符合官方实践的结构化实现方案。

在构建需要“双向通信”的 Telegram Bot 应用时(例如:Bot 主动推送消息给用户,同时接收外部系统通过 HTTP 发起的通知),常需将 aiogram 3 的轮询机器人与 aiohttp Web 服务共存于同一 Python 进程中。但直接调用 dp.start_polling() 和 web.run_app() 会引发冲突——因为二者都试图接管事件循环,且 web.run_app() 是阻塞式入口函数,不可与 asyncio.run() 或手动 loop.run_until_complete() 混用。

✅ 正确做法是:让 aiohttp 成为“主应用”,通过 cleanup_ctx 上下文管理器异步启动并生命周期托管 aiogram 任务。这种方式更健壮、可扩展,且与 aiohttp 官方推荐的复杂应用架构一致(见 aiohttp 文档 - Complex Applications)。

以下是一个生产就绪的完整示例:

达奇AI论文写作
达奇AI论文写作

达奇AI论文辅助写作平台,在校学生、职场精英都在用的AI论文辅助写作平台

下载
import asyncio
import logging
from contextlib import suppress
from aiogram import Bot, Dispatcher
from aiohttp import web

# 配置日志(建议启用)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

TOKEN = "YOUR_BOT_TOKEN_HERE"

# 1. 定义 bot 启动逻辑(作为独立协程)
async def start_aiogram_bot():
    bot = Bot(TOKEN, parse_mode="HTML")
    dp = Dispatcher()

    # ✅ 注册你的处理器(如 /start、消息处理等)
    # @dp.message(Command("start"))
    # async def cmd_start(message: Message):
    #     await message.answer("Hello from aiogram!")

    logger.info("Starting aiogram bot in polling mode...")
    await dp.start_polling(bot)

# 2. 定义 aiohttp Web 服务(含 bot 生命周期管理)
async def init_web_app() -> web.Application:
    app = web.Application()

    # ✅ 使用 cleanup_ctx 确保 bot 与 web server 共享同一事件循环
    # 并在应用关闭时优雅终止 bot 任务
    async def run_bot_task(_app):
        task = asyncio.create_task(start_aiogram_bot())

        yield  # 应用运行期间保持 bot 活跃

        # 清理阶段:取消 bot 任务
        task.cancel()
        with suppress(asyncio.CancelledError):
            await task  # 等待任务完全退出,抛出异常(如有)

    app.cleanup_ctx.append(run_bot_task)

    # ✅ 添加你的 HTTP 处理器(例如接收外部通知)
    async def handle_notify(request):
        try:
            data = await request.json()
            user_id = data.get("user_id")
            text = data.get("text", "Notification received.")

            # 注意:此处需访问 bot 实例 —— 推荐使用全局变量或依赖注入
            # 实际项目中建议通过 app['bot'] 注入(见进阶说明)
            # 示例暂略 bot 发送逻辑(需确保 bot 实例可访问)

            return web.json_response({"status": "ok", "received": True})
        except Exception as e:
            logger.error(f"Failed to handle notify: {e}")
            return web.json_response({"error": str(e)}, status=400)

    app.router.add_post("/notify", handle_notify)

    return app

# 3. 启动入口(标准 aiohttp 方式)
if __name__ == "__main__":
    web_app = init_web_app()
    web.run_app(web_app, host="127.0.0.1", port=5555)

? 关键要点说明

  • web.run_app() 是 aiohttp 的顶层运行器,它内部调用 asyncio.run(),因此不应再手动获取/操作事件循环(如 get_event_loop()、create_task() 等);
  • cleanup_ctx 是 aiohttp 提供的生命周期钩子:yield 前执行初始化(启动 bot),yield 后执行清理(取消 bot);
  • bot 任务被包裹在 asyncio.create_task() 中,保证其在后台持续运行,不阻塞 Web 路由响应;
  • 所有异步资源(如数据库连接、HTTP 客户端)均可通过 app['key'] 注入并在 cleanup_ctx 中统一释放,提升可维护性。

⚠️ 注意事项

  • 若需在 Web handler 中调用 bot.send_message(),请将 Bot 实例存储于 app['bot'](在 run_bot_task 初始化后赋值),而非创建新实例;
  • 避免在 start_aiogram_bot() 内部直接使用 await dp.start_polling() 后继续执行其他逻辑——start_polling() 是长期运行协程,会阻塞后续代码;cleanup_ctx 的 yield 正是为此设计;
  • 开发调试时可添加 --reload 支持(需 aiohttp-devtools),但注意热重载可能干扰 bot 状态,生产环境应禁用。

通过该结构,你获得了一个统一调度、生命周期可控、易于监控和部署的混合异步服务,兼顾 Telegram 交互与外部系统集成能力。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

379

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2105

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

356

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

259

2023.09.05

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

329

2023.10.09

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

419

2023.10.16

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

462

2023.10.16

vb连接数据库的方法
vb连接数据库的方法

vb连接数据库的方法有使用ADO对象库、使用OLEDB数据提供程序、使用ODBC数据源等。详细介绍:1、使用ADO对象库方法,ADO是一种用于访问数据库的COM组件,可以通过ADO连接数据库并执行SQL语句。可以使用ADODB.Connection对象来建立与数据库的连接,然后使用ADODB.Recordset对象来执行查询和操作数据;2、使用OLEDB数据提供程序方法等等。

230

2023.10.19

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

45

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号