feat: enhance WebSocket connection handling and improve MTProto trans…#233
feat: enhance WebSocket connection handling and improve MTProto trans…#233DanielLavrushin wants to merge 1 commit into
Conversation
|
There was a problem hiding this comment.
Pull request overview
This PR improves MTProto upstream connection reliability (especially WebSocket routing) by rotating across multiple known-good Telegram WS edge IPs and by refactoring/removing the WS connection pool. It also updates the Web UI “Connections” page to base filtering/timestamps on the connection data’s timestamps (to avoid issues when the viewer device clock is skewed).
Changes:
- MTProto: rotate WS-edge dial targets across a default IP set and refactor WS/TCP cooldown + logging state into a dedicated module; remove the WS prewarm pool and simplify dialing call sites.
- Tests: update transport-planning tests to account for multiple WS plans per SNI (per-IP fan-out).
- Web UI: adjust connections aggregation and “now” handling to rely on data timestamps; minor Discovery UI layout/formatting updates; document the Connections-page clock-skew fix in the changelog.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/mtproto/wsstate.go | New shared WS/TCP cooldown/blacklist + dial-error throttling state moved out of the removed pool. |
| src/mtproto/wspool.go | Removes WS pool implementation (prewarmed connections). |
| src/mtproto/transparent.go | Removes pool lifecycle and switches transparent bridge dialing to DialObfuscatedDC. |
| src/mtproto/server.go | Removes server-held WS pool and switches dialing to DialObfuscatedDC. |
| src/mtproto/plantransports_test.go | Updates tests for WS plan fan-out across multiple edge IPs and validates anti-funneling behavior. |
| src/mtproto/obfuscated2.go | Adds WS edge IP rotation + fans out native-edge WS plans per IP; removes pooled dial path. |
| src/http/ui/src/workers/connections-aggregator.worker.ts | Uses data timestamps as the “now” basis; tracks latestTs. |
| src/http/ui/src/components/discovery/Discovery.tsx | UI formatting/conditional rendering adjustments for log panel and handlers. |
| src/http/ui/src/components/connections/views/AggregatedView.tsx | Changes time-window cutoff and “now” derivation to use data timestamps (removes browser nowTick). |
| changelog.md | Adds release note about fixing Connections page behavior when device clock is out of sync. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const cleanTs = rawTs.replaceAll(" [INFO]", "").trim().split(".")[0]; | ||
| const ts = Date.parse(cleanTs.replaceAll("/", "-")) || Date.now(); | ||
| const ts = Date.parse(cleanTs.replaceAll("/", "-")) || latestTs; |
| const state = useConnectionGroups(lines, deviceMap, paused); | ||
|
|
||
| useEffect(() => { | ||
| const id = globalThis.setInterval(() => setNowTick(Date.now()), 1000); | ||
| return () => globalThis.clearInterval(id); | ||
| }, []); | ||
| const now = useMemo(() => { | ||
| let latest = 0; | ||
| for (const g of state.groups) if (g.lastSeen > latest) latest = g.lastSeen; | ||
| for (const d of state.devices) if (d.lastSeen > latest) latest = d.lastSeen; | ||
| return latest; | ||
| }, [state.groups, state.devices]); |
| hosts := wsEdgeDialHosts(cfg) | ||
| primarySNI := fmt.Sprintf("kws%d.web.telegram.org", absDC) | ||
| mediaSNI := fmt.Sprintf("kws%d-1.web.telegram.org", absDC) | ||
| sniOrder := []string{primarySNI, mediaSNI} | ||
| if dc < 0 { |
| func wsRecordFailure(dc int, allRedirect bool) { | ||
| k := wsKeyFromDC(dc) | ||
| wsStateMu.Lock() | ||
| defer wsStateMu.Unlock() | ||
| if allRedirect { | ||
| wsBlacklist[k] = true | ||
| log.Warnf("MTProto WS %s blacklisted (all redirects)", k) | ||
| } | ||
| wsCooldownTo[k] = time.Now().Add(wsDCFailCooldown) | ||
| } |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 31 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
abandone this |



…port logic