Skip to content

Data tracks#975

Draft
pblazej wants to merge 7 commits into
mainfrom
blaze/datatracks-integration
Draft

Data tracks#975
pblazej wants to merge 7 commits into
mainfrom
blaze/datatracks-integration

Conversation

@pblazej

@pblazej pblazej commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

No description provided.

pblazej and others added 5 commits June 25, 2026 08:33
Replace remote livekit-uniffi-xcframework dependency with a local path
to the Rust SDK's UniFFI package output, enabling iteration on data
track bindings without publishing releases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire livekit-datatrack Rust managers into the Swift SDK's Room,
SignalClient, and transport infrastructure. Data tracks provide
frame-oriented, real-time data delivery with built-in DTP packetization
and optional E2EE.

Scaffolding (Phase 1):
- Forward raw WebSocket bytes to Rust managers for signal routing
- Create _data_track publisher/subscriber WebRTC data channels
- Delegate bridges for signal requests, DTP packets, and track events
- Manager lifecycle tied to Room connect/disconnect/reconnect
- DataTrackDelegate protocol for track published/unpublished events

Public API (Phase 2):
- LocalParticipant.publishDataTrack(name:) and withDataTrack(name:body:)
- LocalDataTrack.send(contentsOf:) for piping AsyncSequence to a track
- AsyncPolling protocol with .values for DataTrackStream iteration
- DataTrackFrame convenience extensions (.now, .latency)

E2E Tests (Phase 3):
- 8 tests mirroring Rust data_track_test.rs (publish/receive, large
  frames, duplicate name, unauthorized, state, timestamp, resubscribe,
  many tracks)
- Test helper Room.waitForDataTrack(name:) for async track discovery

Tests require livekit-server with enable_data_tracks and a tokio runtime
fix in livekit-uniffi (pending).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Forward serialized protobuf bytes after parsing (not raw WebSocket
  bytes) so JSON-encoded messages from the server are also forwarded
  to Rust data track managers
- Register DataTrackWatcher before publishing to avoid missing the
  initial ParticipantUpdate event
- Use AsyncStream-based watcher for reliable async track discovery
- Simplify resubscribe test to 2 iterations with delay

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Upstream livekit-uniffi replaced the generic `handleSignalResponse`
with specific per-message handlers:
- handleSfuRequestResponse (for RequestResponse)
- handleSfuPublishResponse (for PublishDataTrackResponse)
- handleSfuParticipantUpdate (for ParticipantUpdate)
- handleSubscriberHandles (for DataTrackSubscriberHandles)

Each handler returns UnsupportedType for messages it doesn't handle,
so the simplest integration is to call all four with the raw bytes
and let them filter internally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The 0.31.2 bindings give PushFrameErrorReason cases an associated `message: String` and
conform it to Swift.Error, so `catch PushFrameErrorReason.QueueFull` no longer matches.
Catch the error and pattern-match the case, rethrowing other variants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pblazej pblazej force-pushed the blaze/datatracks-integration branch from cb7f186 to 6c21122 Compare June 25, 2026 11:32
@github-actions

Copy link
Copy Markdown

⚠️ This PR does not contain any files in the .changes directory.

pblazej and others added 2 commits June 26, 2026 12:54
- Collapse the two delegate bridges into a single DataTrackBridge that conforms to both
  manager delegate protocols (shared onSignalRequest, one weak-room instance for both).
- Fold the data track channel/manager teardown into a single cleanUpDataTrack().
- Move the reconnect republish/resubscribe calls into the quick/full reconnect sequences
  so each sequence is self-contained and the retry loop stays clean.
- Nest FrameDropPolicy under LocalDataTrack and drop the redundant AsyncPolling Element
  typealias (inferred from next()).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dd send backpressure

- E2EE: bridge the UniFFI encryption/decryption providers to the existing E2EEManager via
  internal DataTrackEncryptionProvider/DataTrackDecryptionProvider adapters (the public
  E2EEManager can't adopt an internally-imported protocol directly). They reuse E2EEManager's
  AES-GCM data path (LKRTCDataPacketCryptor over the shared BaseKeyProvider); providers are
  passed only when E2EE is configured so plaintext tracks stay unmarked. Exercised end-to-end
  by the existing DataTrackTests, which run with E2EE on by default.
- Attach remote data tracks to their RemoteParticipant (keyed by SID) so they can be
  enumerated, mirroring media tracks and the JS SDK.
- Drop a whole frame when the publisher data track channel is congested instead of sending
  unconditionally, bounding the channel buffer (parity with the lossy data channel threshold).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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