我在同一个循环中使用teleton和quart。我需要收听新消息,同时我想在加载页面时阅读所有频道。
但这样做将以ConnectionError: Cannot send requests while disconnected
结束,我不知道如何处理。在循环之前添加async with client:
将导致sqlite3.OperationalError: database is locked
。有机会归档我想要的东西吗?
这里的相关代码:
...
executor = ProcessPoolExecutor(1)
...
# 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')
...
@app.before_serving
async def startup():
client.loop.run_in_executor(executor, telethon_start)
...
@client.on(events.NewMessage(incoming=True))
async def new_chat(event):
#Do something with messages
...
@main.route('/new', methods=['GET', 'POST'])
async def new():
channels = []
async for dialog in client.iter_dialogs(): # Here the problem
channels.append((dialog.id, dialog.name))
return await render_template(
'new_channel.html',
channels=channels
)
def telethon_start():
with client:
client.run_until_disconnected()
async def start(conf):
app.register_blueprint(main, url_prefix=base_url)
await hypercorn.asyncio.serve(app, conf)
if __name__ == '__main__':
config = hypercorn.Config()
config.bind = "127.0.0.1:" + str(expose_port)
client.loop.run_until_complete(start(config))
请帮帮我!
executor
的用法似乎可疑。你不应该真的需要它。
假设每次请求发生时都调用@app.before_serving
,那么每个请求也将多次连接同一客户端。这是错误的,因为理想情况下每个客户端实例只应连接一次(不能多次重用同一会话(。
我的建议是,你只需在提供应用程序之前连接客户端,如下所示:
# @app.before_serving, startup and telethon_start removed entirely
async def start(conf):
async with client:
# ^~~~~~~~~~~ starting the client now occurs here
app.register_blueprint(main, url_prefix=base_url)
await hypercorn.asyncio.serve(app, conf)