Telethon,全局变量停止 websocket

Posted

技术标签:

【中文标题】Telethon,全局变量停止 websocket【英文标题】:Telethon, global variable stops websocket 【发布时间】:2021-10-31 13:03:49 【问题描述】:

所以,我正在尝试使用 Telethon、quart 和 websockets 来创建一个动态页面,该页面仅在客户端收到消息事件时才接收更新:

from telethon import TelegramClient, connection, events, utils
import hypercorn.asyncio
from quart import Quart, websocket

from variables import api_id, api_hash

from datetime import datetime
import asyncio

# Session name, API ID and hash to use; loaded from environmental variables
SESSION = 'quart';

# Telethon client
client = TelegramClient(SESSION, api_id, api_hash)
client.parse_mode = 'html'  


###paginas html
teste_html = """
<!doctype html>
<html>
  <head>
    <title>Quart + Telethon</title>
    <link rel="stylesheet" type="text/css" href="/static/style.css">
  </head>
  <body>
    <h1>Página de teste!</h1>
    <p>No momento, estamos testando o websocket</p>
    <ul></ul>
    <script type="text/javascript">
    let socket = new WebSocket('ws://localhost:8000/random');

    socket.onmessage = function(event) 
        var messages_dom = document.getElementsByTagName('ul')[0];
        var message_dom = document.createElement('li');
        var cotent_dom = document.createTextNode('Received: ' + event.data);
        message_dom.appendChild(cotent_dom);
        messages_dom.appendChild(message_dom);
    ;
    </script>
    
  </body>
</html>
"""

###

app = Quart(__name__)
lock = asyncio.Lock();


@app.before_serving
async def startup():
    await client.connect()


@app.after_serving
async def cleanup():
    await client.disconnect()

@client.on(events.NewMessage)
async def receber(event):
    global x;
    try:
        sender = await event.get_sender();
        name = utils.get_display_name(sender);
        message = name + "::::::" + event.text + "\n";
        await lock.acquire();
        x = message;
        try:
            file = open('msg.txt', '+a');
            file.write(message);
            file.close();

        finally:
            lock.release()

    except(KeyboardInterrupt):
        print("Adeus!");

    except Exception as e:
        print("\n======ERRO======\n");
        print(e);


###websockets
@app.websocket('/random')
async def random():
    global x;
    import random
    from time import sleep

    try:
        while True:
            if x != 1:
                print(x);
                data = random.randint(0,5);
                data = str(data);
                await websocket.send(f"Quart enviou 1: data");
            else:
                besteira = 0;

            sleep(1);
            
    except Exception as e:
        print(e);
        print("erro 2");


@app.route('/')
async def hello_world():
    await client.send_message('me', 'Hello World')
    #return 'Message Sent!'
    return teste_html;

async def main():
    await hypercorn.asyncio.serve(app, hypercorn.Config())

if __name__ == '__main__':
    x = 1;
    try:
        client.loop.run_until_complete(main())

    except KeyboardInterrupt:
        print("Adeus!");

    except Exception as e:
        print(e);

这个想法是,当收到第一条新消息时,websocket 将开始向页面发送随机数(我是初学者),但是,它只是锁定,甚至不会写入 msg.txt 文件,这里是细的,只有当你使用 if 语句时才会发生这种情况。如果你把 if 语句拿掉,它会运行,慢,但它会运行,但如果你把 if 语句,它只是锁定。

如果你不能帮助我,你能推荐我任何 quart/telethon/websocket 教程吗?还是一个例子?如果没有,还有其他方法可以做到这一点吗?有没有更好的方法来创建动态页面?

非常欢迎任何帮助。

【问题讨论】:

【参考方案1】:

解决方案是我是白痴,我使用的是同步睡眠,我不知道这到底是怎么破坏的,但确实如此,这是固定的 API:

@app.websocket('/random')
async def random():
    global mensagem;
    import random
    #from time import sleep
    mensagem_antiga = "";
    
    try:
        for i in range(1, 1000):
            
            if mensagem_antiga != mensagem:
                await websocket.send(f" mensagem");
                mensagem_antiga = mensagem;

            await asyncio.sleep(1);
            
            
    except Exception as e:
        print(e);
        print("erro 2");

【讨论】:

同步睡眠使整个线程进入睡眠状态,因此asyncio 事件循环无法运行(因此,所有async 事物都“停止”)。 是的,经过 2 天的研究,我意识到了这一点,无论如何,谢谢! PS:@Lonami 我只想说我喜欢使用 Telethon,你创造的东西简直太棒了!保持伟大的工作!

以上是关于Telethon,全局变量停止 websocket的主要内容,如果未能解决你的问题,请参考以下文章

在 ES Lint 中将 WebSocket 定义为 React Native 应用程序的全局

如何让两个 Telethon 客户端各自使用不同的 IP

如何使用 Telethon 获取电报私人频道 ID

Python 和 Telethon:登录错误 UPDATE_APP_TO_LOGIN

在 Django 中全局存储动态变量

如何绑定到 Emberjs 中的全局变量