我正在尝试使用多个客户端运行Quart+Telethon。这个例子显示了一个全局客户端。我已经开始工作了。
现在,我需要我的应用程序来处理多个用户,同时登录和做一些事情。这个职位建议使用asyncio.gather。
如何更改代码以便让多个人登录?
在这里,我将夸脱功能的大部分放在work()函数中(在引用客户机的地方)。在def ()中,我启动应用程序,然后调用asyncio.gather。
当在asyncio.gather中使用两个work()函数(两个客户端)运行应用程序时,我得到错误"AssertionError: Handler正在覆盖端点phone_form的存在“。
如果只使用一个work()函数运行,则会得到一个不同的错误:“ConnectionError(‘不能在断开连接时发送请求’)。”
我遗漏了什么?Thx
import os
import asyncio
from dotenv import load_dotenv
from quart import Quart, render_template_string, request, render_template
from telethon import TelegramClient
load_dotenv('.env')
API_ID = int(os.getenv('API_ID'))
API_HASH = str(os.getenv('API_HASH'))
app = Quart(__name__)
async def work(client):
async with client:
@app.route("/")
async def phone_form():
return await render_template('phone_form.html')
@app.route("/validation_form", methods=['POST'])
async def validation_form():
""" Ask the user for the confirmation code they just got. """
global phone
# Check form parameters (phone/code)
form = await request.form
if 'phone' in form:
phone = form['phone']
await client.send_code_request(phone)
return await render_template('validation_form.html', phone_nr=phone)
async def main():
import hypercorn.asyncio
# create task so that starting hypercorn server is no blocking functions that come after it
server = asyncio.create_task(hypercorn.asyncio.serve(app, hypercorn.Config()))
# have many clients here, using the app asynchronously
await asyncio.gather(
work(TelegramClient('user1', API_ID_, API_HASH)),
work(TelegramClient('user2', API_ID, API_HASH)),
)
# this is to start blocking - means after this subsequent functions will need to wait until hypercorn is finished (hypercorn runs forever!)
# this await also lets server run indefinitely
await server
if __name__ == '__main__':
asyncio.run(main())发布于 2022-02-27 14:18:16
代码试图将N个函数处理程序设置为相同的路由,这就是导致这里出现错误的原因。我相信您在这里需要一种不同的方法--使添加会话成为一个处理上一个(新的)会话的路由的连续过程。
我不确定如何启动超级玉米服务器,因此使用它是您示例中的一部分。
例如:
API_ID = int(os.getenv('API_ID'))
API_HASH = str(os.getenv('API_HASH'))
app = Quart(__name__)
clients = []
async def work():
new_cli = None
phone = None
@app.route("/")
async def index():
""" Some page containing 'new session' button redirecting to /phone_form """
new_cli = None
phone = None
return render_template('index.html')
@app.route("/phone_form")
async def phone_form():
num = len(clients) + 1
new_cli = TelegramClient(f'user{num}', API_ID_, API_HASH)
await new_cli.connect()
return await render_template('phone_form.html')
@app.route("/validation_form", methods=['POST'])
async def validation_form():
""" Ask the user for the confirmation code they just got. """
# Check form parameters (phone/code)
form = await request.form
if 'phone' in form:
phone = form['phone']
await client.send_code_request(phone)
return await render_template('validation_form.html', phone_nr=phone)
@app.route("/confirm_code", methods=['POST'])
async def confirm_code():
""" Finish auth process. """
form = await request.form
if 'code' in form:
await new_cli.sign_in(phone, form['code'])
clients.append(new_cli)
new_cli = None
phone = None
async def main():
import hypercorn.asyncio
server = asyncio.create_task(hypercorn.asyncio.serve(app, hypercorn.Config()))
await work()
await server
if __name__ == '__main__':
asyncio.run(main())如果出现新的客户端会话,您还可能希望添加检查器。生成的会话可以在以后使用。
https://stackoverflow.com/questions/71261291
复制相似问题