Telethon与Quart同循环运行时请求失败及数据库锁问题求助
解决方案
核心思路
把Telethon客户端的启动和Quart服务的运行放到同一个异步事件循环中,避免多进程共享数据库文件导致的锁问题,同时保证客户端在请求时处于连接状态。
修改后的完整代码示例
import asyncio from hypercorn.asyncio import serve from hypercorn.config import Config from quart import Quart, Blueprint, render_template from telethon import TelegramClient, events # 配置参数(自行替换为你的实际值) api_id = 123456 api_hash = 'your_api_hash_here' base_url = '/' expose_port = 5000 # Telethon client client = TelegramClient('bot', int(api_id), api_hash) # Quart app app = Quart(__name__, template_folder=None, static_folder=None, static_url_path=None) main = Blueprint('main', __name__, template_folder='templates', static_folder='static', static_url_path='static') # 监听新消息的事件处理器 @client.on(events.NewMessage(incoming=True)) async def new_chat(event): # 处理新消息逻辑 print(f"收到新消息: {event.message.text}") # Quart路由:获取频道列表 @main.route('/new', methods=['GET', 'POST']) async def new(): channels = [] # 直接使用已连接的客户端遍历对话 async for dialog in client.iter_dialogs(): channels.append((dialog.id, dialog.name)) return await render_template( 'new_channel.html', channels=channels ) async def startup(): # 启动Telethon客户端 await client.start() # 确保客户端一直运行(不会阻塞,因为是异步的) asyncio.create_task(client.run_until_disconnected()) async def start(conf): app.register_blueprint(main, url_prefix=base_url) # 在启动Quart服务前先启动Telethon await startup() await serve(app, conf) if __name__ == '__main__': config = Config() config.bind = "127.0.0.1:" + str(expose_port) # 运行主异步函数 asyncio.run(start(config))
关键修改点说明
- 移除ProcessPoolExecutor:不再用多进程隔离Telethon,因为Telethon本身是异步的,和Quart可以共存于同一个事件循环。
- 异步启动Telethon:在
startup函数中用await client.start()启动客户端,然后用asyncio.create_task把client.run_until_disconnected()作为后台任务运行,不会阻塞Quart服务。 - 统一事件循环:所有异步操作(Telethon消息监听、Quart请求处理)都在同一个
asyncio.run()启动的事件循环里执行,保证客户端在请求时处于已连接状态。 - 避免数据库锁:只有一个进程操作Telethon的SQLite会话文件,彻底解决
sqlite3.OperationalError: database is locked问题。
额外注意事项
- 如果你的消息处理逻辑有耗时操作(比如IO密集或CPU密集任务),不要直接在
new_chat里同步执行,应该用asyncio.create_task或者线程池(loop.run_in_executor)异步处理,避免阻塞事件循环。 - 确保Telethon的会话文件(
bot.session)所在目录有读写权限。
内容的提问来源于stack exchange,提问作者Paolo7297
相关产品推荐
相关产品推荐

