@dodoshaurma

Как убрать задержку в WebSockets?

Подключился к бирже Binance по сокетам.
Когда происходит нужное событие, то появляется сигнал в Telegram.
Но сравнив время сигнала в Telegram и на графике – вижу разницу в 5-12 мин., от случая к случаю...

Как это разрешить?

Скелет кода такой: в функции on_message своей логики навалил, 40 монет отслеживаю.
Может быть дело в количестве монет.

import websocket
import _thread
import time
import rel

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws, close_status_code, close_msg):
    print("### closed ###")

def on_open(ws):
    print("Opened connection")

if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("wss://api.gemini.com/v1/marketdata/BTCUSD",
                              on_open=on_open,
                              on_message=on_message,
                              on_error=on_error,
                              on_close=on_close)

ws.run_forever(dispatcher=rel, reconnect=5)  # Set dispatcher to automatic reconnection, 5 second reconnect delay if connection closed unexpectedly  
rel.signal(2, rel.abort)  # Keyboard Interrupt
<Signal Object | Callback:"abort">
rel.dispatch()
  • Вопрос задан
  • 300 просмотров
Пригласить эксперта
Ответы на вопрос 3
fenrir1121
@fenrir1121
Начни с документации
в функции on_message своей логики навалил, 40 монет отслеживаю.
Может быть дело в кол-ве монет.

Так и проверьте на одной монете.
Сделаю предположение, что с вашей обработкой в лоб без использования асинхронности и мультипроцессинга ваша обработка непоспевает за сообщениями и накапливается отставание.

Я бы протестировал на одной, а затем переписал на го или расте, которые значительно лучше приспособлены для распараллеливания cpu-bound задач.
Ответ написан
@rPman
Это не вебсокет вносит задержки, а телеграм. Задержки в рассылке сообщений клиентам у него доходят до нескольких минут, это не исправить, клиенты должны сами подключаться к тому же серверу что и бот, управлять этим невозможно.
Ответ написан
Комментировать
@Andrey228top
Проблема с задержкой сигнала может быть связана с несколькими факторами, такими как нагрузка на сервер, количество отслеживаемых монет, а также задержки при отправке сообщений в Telegram. Вот несколько рекомендаций для улучшения времени отклика:

1. **Использование многопоточности или асинхронного подхода**: Обработка сообщений для 40 монет может занять время. Перейти на асинхронную обработку сообщений или использовать многопоточность для уменьшения задержек.

2. **Оптимизация логики обработки сообщений**: Убедитесь, что логика обработки сообщений оптимизирована и выполняется как можно быстрее.

3. **Таймстемп сообщений**: Добавьте временные метки к сообщениям при их получении и отправке, чтобы точно отслеживать, где возникает задержка.

4. **Увеличение количества сокетов**: Вместо отслеживания всех монет в одном сокете, создайте несколько сокетов и распределите монеты между ними.

5. **Использование WebSocket для Telegram**: Вместо использования обычного метода для отправки сообщений в Telegram, рассмотрите использование WebSocket для отправки сообщений, чтобы уменьшить задержку.

Обновим ваш код для использования асинхронного подхода с помощью библиотеки `asyncio` и `websockets`, а также для отправки сообщений в Telegram:

```python
import asyncio
import websockets
import json
import aiohttp

# Function to send message to Telegram
async def send_telegram_message(token, chat_id, message):
async with aiohttp.ClientSession() as session:
url = f"https://api.telegram.org/bot{token}/sendMessage"
payload = {
'chat_id': chat_id,
'text': message
}
async with session.post(url, data=payload) as resp:
return await resp.text()

async def on_message(message):
print(message)
# Add your message processing logic here

# Example: Send message to Telegram
telegram_token = "YOUR_TELEGRAM_BOT_TOKEN"
chat_id = "YOUR_CHAT_ID"
await send_telegram_message(telegram_token, chat_id, message)

async def listen():
uri = "wss://api.gemini.com/v1/marketdata/BTCUSD"
async with websockets.connect(uri) as websocket:
while True:
message = await websocket.recv()
await on_message(message)

if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(listen())
```

Этот код использует библиотеку `aiohttp` для асинхронного отправки сообщений в Telegram и `websockets` для асинхронного подключения к WebSocket. Теперь обработка сообщений и отправка в Telegram будет происходить быстрее, что должно уменьшить задержку.

Кроме того, если вы отслеживаете 40 монет, можно использовать несколько WebSocket соединений, чтобы разделить нагрузку.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы