[PR #925] [MERGED] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646) #74

Closed
opened 2026-07-19 11:34:40 +03:00 by mirror-bot · 0 comments

📋 Pull Request Information

Original PR: https://github.com/Flowseal/tg-ws-proxy/pull/925
Author: @f4rceful
Created: 5/31/2026
Status: ✅ Merged
Merged: 6/17/2026
Merged by: @Flowseal

Base: main ← Head: fix/ws-keepalive-646


📝 Commits (1)

  • fd3371b fix: add WebSocket keepalive pings to prevent idle disconnects (#646)

📊 Changes

4 files changed (+34 additions, -1 deletions)

View changed files

📝 proxy/bridge.py (+21 -1)
📝 proxy/config.py (+1 -0)
📝 proxy/raw_websocket.py (+7 -0)
📝 proxy/tg_ws_proxy.py (+5 -0)

📄 Description

## Что сделано

  • Добавлен RawWebSocket.send_ping() — отправка WS-фрейма OP_PING (маскированного, как требует протокол для клиента).
  • Добавлен цикл _ws_keepalive() в bridge_ws_reencrypt, который шлёт PING на upstream каждые --ws-keepalive секунд (по умолчанию 30, 0 — отключить).
  • Флаг --ws-keepalive SEC в CLI и поле ws_keepalive_interval в ProxyConfig (дефолт 30с — фикс активен и для GUI/трея).

Зачем (разбор #646)

Долгие сессии рвались через случайный интервал простоя: Telegram показывал «прокси использует некорректные настройки», хотя сам прокси оставался жив, а мгновенное переподключение всё чинило.

Причина — тихий обрыв простаивающего соединения. Прокси отвечал на входящие PING, но сам не слал keepalive, и SO_KEEPALIVE не выставлялся. Stateful-устройство на пути (NAT-таблица домашнего роутера / мобильный CGNAT, либо idle-таймаут CF edge) выкидывает простаивающий поток; следующий пакет упирается в мёртвое соединение → RST. Тот же симптом в независимой go-реализации указывает на причину в транспорте/NAT, а не в Python-коде.

Периодический PING держит NAT-маппинги «тёплыми». Дополнительно: при сбое отправки пинга сессия теперь закрывается сразу, а не висит до следующего пакета клиента.

Поведение по умолчанию

Keepalive включён (30с). Отключить: --ws-keepalive 0.

Как проверить

  • py_compile для proxy/bridge.py, proxy/raw_websocket.py, proxy/config.py, proxy/tg_ws_proxy.py — без ошибок.
  • Полевая проверка пройдена: Telegram Desktop через прокси, простой 15 минут — сессия осталась живой, сообщения уходят мгновенно без переподключения (раньше на той же сети рвалось).
  • Локально проверено юнит-тестами: корректность фрейма PING (пустой и с payload под маской), исключение при закрытом сокете, цикл шлёт пинги повторно / чисто отменяется / выходит при ошибке отправки / отключён при interval<=0.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Flowseal/tg-ws-proxy/pull/925 **Author:** [@f4rceful](https://github.com/f4rceful) **Created:** 5/31/2026 **Status:** ✅ Merged **Merged:** 6/17/2026 **Merged by:** [@Flowseal](https://github.com/Flowseal) **Base:** `main` ← **Head:** `fix/ws-keepalive-646` --- ### 📝 Commits (1) - [`fd3371b`](https://github.com/Flowseal/tg-ws-proxy/commit/fd3371bc9b041853557d9cbdcf160f9e498c9329) fix: add WebSocket keepalive pings to prevent idle disconnects (#646) ### 📊 Changes **4 files changed** (+34 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `proxy/bridge.py` (+21 -1) 📝 `proxy/config.py` (+1 -0) 📝 `proxy/raw_websocket.py` (+7 -0) 📝 `proxy/tg_ws_proxy.py` (+5 -0) </details> ### 📄 Description ## Что сделано - Добавлен `RawWebSocket.send_ping()` — отправка WS-фрейма OP_PING (маскированного, как требует протокол для клиента). - Добавлен цикл `_ws_keepalive()` в `bridge_ws_reencrypt`, который шлёт PING на upstream каждые `--ws-keepalive` секунд (по умолчанию **30**, `0` — отключить). - Флаг `--ws-keepalive SEC` в CLI и поле `ws_keepalive_interval` в `ProxyConfig` (дефолт 30с — фикс активен и для GUI/трея). ## Зачем (разбор #646) Долгие сессии рвались через случайный интервал простоя: Telegram показывал «прокси использует некорректные настройки», хотя сам прокси оставался жив, а мгновенное переподключение всё чинило. Причина — тихий обрыв простаивающего соединения. Прокси **отвечал** на входящие PING, но **сам не слал** keepalive, и `SO_KEEPALIVE` не выставлялся. Stateful-устройство на пути (NAT-таблица домашнего роутера / мобильный CGNAT, либо idle-таймаут CF edge) выкидывает простаивающий поток; следующий пакет упирается в мёртвое соединение → RST. Тот же симптом в независимой **go-реализации** указывает на причину в транспорте/NAT, а не в Python-коде. Периодический PING держит NAT-маппинги «тёплыми». Дополнительно: при сбое отправки пинга сессия теперь закрывается сразу, а не висит до следующего пакета клиента. ## Поведение по умолчанию Keepalive **включён** (30с). Отключить: `--ws-keepalive 0`. ## Как проверить - `py_compile` для `proxy/bridge.py`, `proxy/raw_websocket.py`, `proxy/config.py`, `proxy/tg_ws_proxy.py` — без ошибок. - **Полевая проверка пройдена:** Telegram Desktop через прокси, простой 15 минут — сессия осталась живой, сообщения уходят мгновенно без переподключения (раньше на той же сети рвалось). - Локально проверено юнит-тестами: корректность фрейма PING (пустой и с payload под маской), исключение при закрытом сокете, цикл шлёт пинги повторно / чисто отменяется / выходит при ошибке отправки / отключён при interval<=0. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
mirror-bot added the pull-request label 2026-07-19 11:34:40 +03:00
mirror-bot changed title from [PR #925] [MERGED] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646) to [PR #925] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646) 2026-07-20 04:11:09 +03:00
mirror-bot changed title from [PR #925] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646) to [PR #925] [MERGED] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646) 2026-07-20 23:14:58 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Utilities/tg-ws-proxy#74