Skip to content

feat: smart LAN/tunnel URL switching for remote connections#179

Open
jfversluis wants to merge 1 commit intomainfrom
feat/smart-network-url-switching
Open

feat: smart LAN/tunnel URL switching for remote connections#179
jfversluis wants to merge 1 commit intomainfrom
feat/smart-network-url-switching

Conversation

@jfversluis
Copy link
Collaborator

Problem

When connecting a mobile device to a desktop PolyPilot server, users must choose between a LAN address (fast, only works on same network) or a DevTunnel URL (works everywhere, slower). If the user scans a LAN QR code and then leaves the house, the connection breaks with no fallback.

Solution

The app now stores both URLs and automatically picks the best one:

How it works

  1. QR codes encode both URLs when both sharing modes are active (DevTunnel + Direct Connection)
  2. At connect time, the app probes the LAN address first (2-second HTTP timeout):
    • ✅ LAN reachable → use fast local connection
    • ❌ LAN unreachable → fall back to tunnel
    • 📱 On cellular (no WiFi) → skip LAN probe entirely, use tunnel
  3. On reconnect, re-resolves which URL to use — network may have changed
  4. Connectivity monitoring (iOS/Android) — debounced MAUI Connectivity.ConnectivityChanged events detect WiFi↔cellular transitions

New fields

Field Purpose
ConnectionSettings.LanUrl LAN server address (e.g., http://192.168.1.5:4322)
ConnectionSettings.LanToken Server password for LAN auth

QR code format (backward compatible)

{
  "url": "https://xxx.devtunnels.ms",
  "token": "tunnel-jwt",
  "lanUrl": "http://192.168.1.5:4322",
  "lanToken": "server-password"
}

Old QR codes without lanUrl continue to work — single-URL mode, no probing overhead.

Edge cases handled

Scenario Behavior
Only LAN, no tunnel Uses LAN directly, no probe
Only tunnel, no LAN Uses tunnel directly, no probe
LAN IP changed 2s probe fails → tunnel fallback
WiFi → cellular Reconnect re-resolves to tunnel
Cellular → WiFi Reconnect probes LAN first

Files changed (9 files)

  • ConnectionSettings.cs — LanUrl/LanToken properties
  • WsBridgeClient.cs — ConnectSmartAsync, ResolveUrlAsync, ProbeLanAsync, IsCellularOnly
  • IWsBridgeClient.cs — new interface methods
  • CopilotService.Bridge.cs — ToWebSocketUrl helper, smart connect routing, connectivity monitor
  • CopilotService.cs — accept LanUrl-only configs
  • Dashboard.razor — parse/save LanUrl from QR scan
  • Settings.razor — QR generation includes both URLs, validation accepts LanUrl
  • TestStubs.cs — stub updates
  • SmartUrlResolutionTests.cs25 new tests

Tests

All 1169 tests pass (25 new + 1144 existing). 1 pre-existing locale-dependent failure unrelated.

When mobile connects to a desktop server, the app now stores both URLs
(tunnel and LAN) and automatically picks the best one:

- LAN first: On WiFi, probes the LAN address with a 2s HTTP timeout.
  If reachable, uses the fast local connection.
- Tunnel fallback: If LAN probe fails or device is on cellular, uses
  the DevTunnel/ngrok URL.
- Smart reconnect: On each reconnect attempt, re-resolves which URL
  to use based on current network state.

Implementation:
- ConnectionSettings: new LanUrl/LanToken fields
- WsBridgeClient: ConnectSmartAsync with LAN probe + ResolveUrlAsync
- QR codes: encode both URLs when both sharing modes are active
- QR scanning: parse lanUrl/lanToken with backward compatibility
- Connectivity monitor (iOS/Android): debounced network change events
  via MAUI Connectivity API
- CopilotService: accepts LanUrl-only configs (no tunnel required)

Includes 25 new tests covering URL resolution, LAN probe, QR parsing,
settings serialization, and backward compatibility.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant