Keepalive, добавленный в #925 (issue #646), отправлял WebSocket-PING фреймы
в апстрим Telegram (/apiws). Этот шлюз не принимает клиентские control-PING
и закрывает соединение при их получении. В результате keepalive, задуманный
чтобы держать соединения живыми, наоборот рубил их ровно на интервале.
Подпись бага в логах: сессии закрывались строго на in 30.1s (= интервал),
причём отсчёт шёл от открытия каждой сессии, а не от последней активности -
рвались даже активные загрузки.
_ws_keepalive слал OP_PING (0x9) в апстрим раз в ws_keepalive_interval
секунд. Для /apiws это нарушение протокола -> сервер присылает CLOSE ->
сессия закрывается. Официальный веб-клиент Telegram WS-пинги не использует
(шлёт MTProto-пинги внутри бинарного потока).
Решение
Keepalive теперь выбирается режимом (настройка + CLI):
tcp (по умолчанию) - OS-level SO_KEEPALIVE на апстрим-сокете.
Пробы живут под TLS, невидимы для прикладного слоя Telegram, держат
NAT/firewall тёплыми (цель #646) и не триггерят разрыв.
ws - прежний WebSocket-PING (legacy; ломается на /apiws).
off - keepalive выключен.
Кросс-платформенно: Windows - SIO_KEEPALIVE_VALS, Linux - TCP_KEEPIDLE/INTVL/CNT, macOS - TCP_KEEPALIVE.
Обратная совместимость
Старый ключ ws_keepalive_interval мигрируется при загрузке конфига: interval > 0 -> tcp (безопасный режим) с сохранением интервала, interval <= 0 -> off. Существующим пользователям ничего перенастраивать
не нужно - их «вредный» конфиг тихо станет безопасным TCP.
ui/ctk_tray_ui.py - селектор режима + поле интервала
🔄 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/1034
**Author:** [@f4rceful](https://github.com/f4rceful)
**Created:** 6/23/2026
**Status:** ❌ Closed
**Base:** `main` ← **Head:** `fix/tcp-keepalive`
---
### 📝 Commits (1)
- [`ae281a9`](https://github.com/Flowseal/tg-ws-proxy/commit/ae281a9bd0d80c0bd9043fa381a180fca16fde78) fix: replace harmful WS-PING keepalive with selectable TCP/WS/off modes (#1023)
### 📊 Changes
**7 files changed** (+190 additions, -14 deletions)
<details>
<summary>View changed files</summary>
📝 `proxy/bridge.py` (+5 -4)
📝 `proxy/config.py` (+3 -1)
📝 `proxy/raw_websocket.py` (+46 -2)
📝 `proxy/tg_ws_proxy.py` (+28 -5)
📝 `ui/ctk_tray_ui.py` (+74 -0)
📝 `utils/default_config.py` (+2 -1)
📝 `utils/tray_common.py` (+32 -1)
</details>
### 📄 Description
## Проблема
Keepalive, добавленный в #925 (issue #646), отправлял WebSocket-PING фреймы
в апстрим Telegram (`/apiws`). Этот шлюз не принимает клиентские control-PING
и закрывает соединение при их получении. В результате keepalive, задуманный
чтобы *держать* соединения живыми, наоборот рубил их ровно на интервале.
Подпись бага в логах: сессии закрывались строго на `in 30.1s` (= интервал),
причём отсчёт шёл от открытия каждой сессии, а не от последней активности -
рвались даже активные загрузки.
Связано с #1023.
## Причина
`_ws_keepalive` слал `OP_PING` (0x9) в апстрим раз в `ws_keepalive_interval`
секунд. Для `/apiws` это нарушение протокола -> сервер присылает CLOSE ->
сессия закрывается. Официальный веб-клиент Telegram WS-пинги не использует
(шлёт MTProto-пинги внутри бинарного потока).
## Решение
Keepalive теперь выбирается режимом (настройка + CLI):
- **`tcp`** (по умолчанию) - OS-level `SO_KEEPALIVE` на апстрим-сокете.
Пробы живут под TLS, невидимы для прикладного слоя Telegram, держат
NAT/firewall тёплыми (цель #646) и не триггерят разрыв.
- **`ws`** - прежний WebSocket-PING (legacy; ломается на `/apiws`).
- **`off`** - keepalive выключен.
Кросс-платформенно: Windows - `SIO_KEEPALIVE_VALS`, Linux -
`TCP_KEEPIDLE/INTVL/CNT`, macOS - `TCP_KEEPALIVE`.
### Обратная совместимость
Старый ключ `ws_keepalive_interval` мигрируется при загрузке конфига:
`interval > 0` -> `tcp` (безопасный режим) с сохранением интервала,
`interval <= 0` -> `off`. Существующим пользователям ничего перенастраивать
не нужно - их «вредный» конфиг тихо станет безопасным TCP.
## Изменения
- `proxy/config.py` - `keepalive_mode` / `keepalive_interval`
- `proxy/raw_websocket.py` - `_enable_tcp_keepalive`, включается только на апстриме
- `proxy/bridge.py` - WS-PING только в режиме `ws`
- `proxy/tg_ws_proxy.py` - `--ws-keepalive-mode`, баннер `Keepalive: …`
- `utils/tray_common.py` - миграция ключа + `apply_proxy_config`
- `utils/default_config.py` - дефолт `tcp` / 30s
- `ui/ctk_tray_ui.py` - селектор режима + поле интервала
---
<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/1034
Author: @f4rceful
Created: 6/23/2026
Status: ❌ Closed
Base:
main← Head:fix/tcp-keepalive📝 Commits (1)
ae281a9fix: replace harmful WS-PING keepalive with selectable TCP/WS/off modes (#1023)📊 Changes
7 files changed (+190 additions, -14 deletions)
View changed files
📝
proxy/bridge.py(+5 -4)📝
proxy/config.py(+3 -1)📝
proxy/raw_websocket.py(+46 -2)📝
proxy/tg_ws_proxy.py(+28 -5)📝
ui/ctk_tray_ui.py(+74 -0)📝
utils/default_config.py(+2 -1)📝
utils/tray_common.py(+32 -1)📄 Description
Проблема
Keepalive, добавленный в #925 (issue #646), отправлял WebSocket-PING фреймы
в апстрим Telegram (
/apiws). Этот шлюз не принимает клиентские control-PINGи закрывает соединение при их получении. В результате keepalive, задуманный
чтобы держать соединения живыми, наоборот рубил их ровно на интервале.
Подпись бага в логах: сессии закрывались строго на
in 30.1s(= интервал),причём отсчёт шёл от открытия каждой сессии, а не от последней активности -
рвались даже активные загрузки.
Связано с #1023.
Причина
_ws_keepaliveслалOP_PING(0x9) в апстрим раз вws_keepalive_intervalсекунд. Для
/apiwsэто нарушение протокола -> сервер присылает CLOSE ->сессия закрывается. Официальный веб-клиент Telegram WS-пинги не использует
(шлёт MTProto-пинги внутри бинарного потока).
Решение
Keepalive теперь выбирается режимом (настройка + CLI):
tcp(по умолчанию) - OS-levelSO_KEEPALIVEна апстрим-сокете.Пробы живут под TLS, невидимы для прикладного слоя Telegram, держат
NAT/firewall тёплыми (цель #646) и не триггерят разрыв.
ws- прежний WebSocket-PING (legacy; ломается на/apiws).off- keepalive выключен.Кросс-платформенно: Windows -
SIO_KEEPALIVE_VALS, Linux -TCP_KEEPIDLE/INTVL/CNT, macOS -TCP_KEEPALIVE.Обратная совместимость
Старый ключ
ws_keepalive_intervalмигрируется при загрузке конфига:interval > 0->tcp(безопасный режим) с сохранением интервала,interval <= 0->off. Существующим пользователям ничего перенастраиватьне нужно - их «вредный» конфиг тихо станет безопасным TCP.
Изменения
proxy/config.py-keepalive_mode/keepalive_intervalproxy/raw_websocket.py-_enable_tcp_keepalive, включается только на апстримеproxy/bridge.py- WS-PING только в режимеwsproxy/tg_ws_proxy.py---ws-keepalive-mode, баннерKeepalive: …utils/tray_common.py- миграция ключа +apply_proxy_configutils/default_config.py- дефолтtcp/ 30sui/ctk_tray_ui.py- селектор режима + поле интервала🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
[PR #1034] [CLOSED] fix: replace harmful WS-PING keepalive with selectable TCP/WS/off modes (#1023)to [PR #1034] fix: replace harmful WS-PING keepalive with selectable TCP/WS/off modes (#1023)[PR #1034] fix: replace harmful WS-PING keepalive with selectable TCP/WS/off modes (#1023)to [PR #1034] [CLOSED] fix: replace harmful WS-PING keepalive with selectable TCP/WS/off modes (#1023)