Skip to content

v1.3.180

Latest

Choose a tag to compare

@topcheer topcheer released this 25 Jul 19:15

v1.3.180

Highlights

  • P2P direct connection: WebRTC DataChannel between Host (Go) and Mobile
    (Flutter) is now stable with P2P-priority protocol, zero message loss, and
    automatic relay fallback.
  • Message loss fix: sendViaTransport now falls back to relay on P2P send
    failure instead of silently dropping messages.
  • Gap detection fix: SyncP2PReplay and TriggerReplayNow use EventID
    matching instead of numeric index, fixing broken gap detection when
    projection store exceeds its 1000-event cap.

Fixes

P2P Message Loss Prevention

Two root causes of messages not reaching mobile have been fixed:

  1. sendViaTransport silently dropped messages on P2P send failure: The
    function returned true even when DataChannel.Send() failed, causing
    senderLoop to skip relay fallback. Now returns false to trigger relay
    fallback — messages are never silently dropped.

  2. Broken gap detection in SyncP2PReplay/TriggerReplayNow: Both
    functions used relayHistoryCount (relay total, can be 2000+) as an array
    index into the projection store capped at 1000 events. When
    relayCount >= localCount, they concluded "no gap" and skipped sync. Fixed:

    • SyncP2PReplay: uses relayLastEventID (Event ID string match) to find
      the suffix in projection events.
    • TriggerReplayNow: replays ALL projection events (mobile deduplicates by
      EventID) instead of computing a broken suffix.

P2P-Priority Protocol

  • SetP2PNegotiating(true) called before handleRelayConnected runs recovery
    plan, preventing relay replay from flooding mobile during P2P negotiation.
  • SyncP2PReplay() sends incremental missing events via DataChannel after P2P
    establishes.
  • TriggerReplayNow() immediately replays missing events to relay after P2P
    failure (not waiting for next reconnect).

Stability

  • signalCh race condition: Each Restart() creates a new channel + 5s
    debounce to coalesce multiple confirmed as client events.
  • ICE timeout: Increased to 25s with SetICETimeouts(15s, 30s, 700ms) for
    TURN/STUN tolerance behind GFW/CGNAT.
  • p2pDone channel: Replaces ctx.Done() for P2P active state — prevents
    ICE timeout from killing an active P2P connection.
  • pion/webrtc logging: Redirected to debug.Log("webrtc", ...) via custom
    LoggerFactory, preventing TUI corruption.
  • Standard log redirect: Third-party libraries using log.Printf are
    redirected to debug.Log("stderr", ...).
  • countTokens debug spam: Removed excessive debug.Log calls from context
    manager.

Documentation

  • Updated docs/design/p2p-direct-connection.md from design proposal to actual
    implementation reference, including architecture diagrams, protocol flow,
    message loss prevention, and debugging guide.

Internal

  • Flutter flutter_webrtc plugin integrated for P2P DataChannel support.
  • Desktop go.mod: pion/webrtc/v4 promoted from indirect to direct dependency.
  • TURN server configured at turn.allpayone.net:8443 with proper realm.

Compare

v1.3.179...v1.3.180