Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changes/single-peer-connection-by-default
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
minor type="changed" "`RoomOptions.singlePeerConnection` now defaults to `true`, matching client-sdk-js and rust-sdks: one ICE/DTLS handshake instead of two, and the publisher offer travels with the JOIN request. Measured ~17% off the post-signal connect phase against LiveKit Cloud. Servers older than LiveKit OSS 1.9.2 fall back to the legacy dual peer connection path automatically; pass `singlePeerConnection: false` to opt out"
12 changes: 9 additions & 3 deletions Sources/LiveKit/Types/Options/RoomOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,13 @@ public final class RoomOptions: NSObject, Sendable, Loggable {

/// Use a single peer connection for both publishing and subscribing.
///
/// - Note: Requires LiveKit Cloud or LiveKit OSS >= 1.9.2.
/// Defaults to `true`, matching client-sdk-js and rust-sdks. One connection means one ICE and
/// DTLS handshake instead of two, and it is the only mode that can carry the publisher offer
/// in the JOIN request — which removes an offer/answer round trip from the connect path.
///
/// - Note: Requires LiveKit Cloud or LiveKit OSS >= 1.9.2. Against an older server the SDK
/// falls back to the legacy dual peer connection path automatically, so setting this has no
/// effect there beyond one extra failed request.
public let singlePeerConnection: Bool

override public init() {
Expand All @@ -79,7 +85,7 @@ public final class RoomOptions: NSObject, Sendable, Loggable {
e2eeOptions = nil
encryptionOptions = nil
reportRemoteTrackStatistics = false
singlePeerConnection = false
singlePeerConnection = true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Default connections intermittently lose data

Default singlePeerConnection enables a mode with reproducible data-channel timeouts. Data messages, RPC calls, and streams can fail for every default connection.

Prompt for agents
Keep the default on the stable dual-peer mode until the intermittent single-peer data-channel timeout is fixed. The failure reproduces in PeerConnectionSignalingTests.dataChannel when singlePeerConnection is true, and this PR makes that path the default for RoomOptions() and the parameterized initializer. Diagnose the channel-open or initial-offer race, add a repeatable regression test, then enable the default only after data messages reliably arrive.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

}

public init(defaultCameraCaptureOptions: CameraCaptureOptions = CameraCaptureOptions(),
Expand All @@ -95,7 +101,7 @@ public final class RoomOptions: NSObject, Sendable, Loggable {
e2eeOptions: E2EEOptions? = nil,
encryptionOptions: EncryptionOptions? = nil,
reportRemoteTrackStatistics: Bool = false,
singlePeerConnection: Bool = false)
singlePeerConnection: Bool = true)
{
self.defaultCameraCaptureOptions = defaultCameraCaptureOptions
self.defaultScreenShareCaptureOptions = defaultScreenShareCaptureOptions
Expand Down