Долгие сессии рвались через случайный интервал простоя: 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>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 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)
fd3371bfix: 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— без ошибок.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
[PR #925] [MERGED] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646)to [PR #925] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646)[PR #925] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646)to [PR #925] [MERGED] fix: WS keepalive-пинги против обрыва простаивающих сессий (#646)