Как правильно подключить вебсокет?

test.py

from socket import create_connection
from time import time as timestamp

class Client():
    def __init__(self, email, password)
        result = requests.post("https://service.narvii.com/api/v1/g/s/auth/login", data=json.dumps(
                              {"email": email, "secret": "0 " + password, "deviceID": "015051B67B8D59D0A86E0F4A78F47367B749357048DD5F23DF275F05016B74605AAB0D7A6127287D9C",
                               "clientType": 100, "action": "normal", "timestamp": (int(timestamp() * 1000))}), 
                                headers={'Content-Type': 'application/json'}).json())
        self.sid = result["sid"]

    def listen(self):
        ws = create_connection(("wss://ws1.narvii.comsignbody=015051B67B8D59D0A86E0F4A78F47367B749357048DD5F23DF275F05016B74605AAB0D7A6127287D9C%7C" + str((int(timestamp() * 1000))) + "&sid=" + self.sid))
        return ws

bot.py

from lib.test import Client

client = Client(<email>, <password>)

while True:
    print(client.listen())

Этот вебсокет присылает информацию о новых сообщениях со всех чатов в которых состоит авторизованный пользователь. Проблема в том, что он часто пропускает сообщения. Я хочу написать бота для этого приложения, и чтобы минимизировать нагрузку, мне нужно его подключить. Читал в интернете о разных способах это сделать, но какой стоит выбрать так и не понял. Как лучше и правильней его подключить?


Ответы (1 шт):

Автор решения: Kers

Как вариант вы постоянно создаете новые соединение create_connection хотя можно было бы работать в одном что несколько снизит нагрузку. Без ограничения по времени в бесконечном цикле это смахивает на DDos.

Пропуск сообщений скорее всего из за того что сервер шлет данные в сокет а Вы уже открыли новый и ждете данные там. Вместо обновления данных в текущем. Хотя это зависит от того как сервер хранит и отсылает данные.

Простой пример для клиента:

from socket import create_connection
ws = socket.create_connection(("127.0.0.1", 8001))
while True:
    ws.send(b"CLIENT\n")
    res = ws.recv(1024)
    print(res)

Упрощенная модель сервера заглушки

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("", 8001))
sock.listen(5)
client, addr = sock.accept()
while True:
    result = client.recv(1024)
    print("Message: ", result.decode("utf-8"))
    client.send(b"TEST MSG!") 
client.close()

Для вашего случая в test.py добавил бы метод:

def start_msg(self):
    ws = сreate_connection(("wss://ws1.narvii.comsignbody=015051B67B8D59D0A86E0F4A78F47367B749357048DD5F23DF275F05016B74605AAB0D7A6127287D9C%7C" + str((int(timestamp() * 1000))) + "&sid=" + self.sid))
    while True:
        ws.send(b"CLIENT\n")
        res = ws.recv(1024)
        print(res)

А в bot.py(а нужен ли он..):

from lib.test import Client

client = Client(<email>, <password>)
client.start_msg()

Единственное вызывают немного сомнения параметры передаваемые в сreate_connection но это это уже вам отлаживать.

→ Ссылка