Skip to content

Add support for RPC V2 - #1087

Merged
hiroshihorie merged 24 commits into
mainfrom
add-rpc-v2
Jun 30, 2026
Merged

hiroshihorie merged 24 commits into
mainfrom
add-rpc-v2

Conversation

@1egoman

@1egoman 1egoman commented May 15, 2026

Copy link
Copy Markdown
Contributor

See this pull request for more info about what this does and how rpc v2 works: livekit/client-sdk-js#1832

Also, for an in depth description of behavior in edge cases, see RPC_SPEC.md here.

Warning

This pull request was LLM generated and has only been lightly reviewed by the author, who is not a flutter expert. I have tested this and can confirm it works in the happy path, but no other validation has been done.

A more thorough review of this needs to occur before it could be merged.

@github-actions

github-actions Bot commented May 15, 2026

Copy link
Copy Markdown

Caution

Breaking change detected without major changeset

dart-apitool detected the following breaking changes:

Preparing git repository: https://github.com/livekit/client-sdk-flutter
Using ref: main
Cloning git repository: https://github.com/livekit/client-sdk-flutter
Checking out ref: main
Successfully cloned to: /tmp/LUTAEA
Preparing package dependencies for git package https://github.com/livekit/client-sdk-flutter (forced Flutter)
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 85.0.0 (104.0.0 available)
  analyzer 7.7.1 (14.0.0 available)
  build 2.5.4 (4.0.6 available)
  build_config 1.1.2 (1.3.0 available)
  build_resolvers 2.5.4 (3.0.4 available)
  build_runner 2.5.4 (2.15.0 available)
  build_runner_core 9.1.2 (9.3.2 available)
  built_value 8.12.4 (8.12.6 available)
  code_assets 1.0.0 (1.2.1 available)
  connectivity_plus 7.1.1 (7.2.0 available)
  dart_style 3.1.1 (3.1.9 available)
  dart_webrtc 1.8.0 (1.8.1 available)
  dbus 0.7.12 (0.7.14 available)
  device_info_plus 12.3.0 (13.2.0 available)
  device_info_plus_platform_interface 7.0.3 (8.1.0 available)
  hooks 1.0.2 (2.0.2 available)
  json_annotation 4.9.0 (4.12.0 available)
  json_serializable 6.9.5 (6.14.0 available)
  matcher 0.12.19 (0.12.20 available)
  meta 1.18.0 (1.18.3 available)
  mockito 5.4.6 (5.7.0 available)
  native_toolchain_c 0.17.6 (0.19.2 available)
  objective_c 9.3.0 (9.4.1 available)
  package_config 2.2.0 (3.0.0 available)
  path_provider 2.1.5 (2.1.6 available)
  path_provider_android 2.2.22 (2.3.1 available)
  path_provider_linux 2.2.1 (2.2.2 available)
  path_provider_platform_interface 2.1.2 (2.1.3 available)
  source_gen 2.0.0 (4.2.3 available)
  source_helper 1.3.7 (1.3.12 available)
  synchronized 3.4.0 (3.4.1 available)
  test_api 0.7.11 (0.7.13 available)
  vector_math 2.2.0 (2.4.0 available)
  vm_service 15.0.2 (15.2.0 available)
  win32 5.15.0 (6.3.0 available)
  win32_registry 2.1.0 (3.0.3 available)
  xml 6.6.1 (7.0.1 available)
Got dependencies!
37 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Resolving dependencies in `./example`...
Downloading packages...
Got dependencies in `./example`.
Preparing . (forced Flutter)
Copying sources from .
Preparing package dependencies for local package . (forced Flutter)
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 85.0.0 (104.0.0 available)
  analyzer 7.7.1 (14.0.0 available)
  build 2.5.4 (4.0.6 available)
  build_config 1.1.2 (1.3.0 available)
  build_resolvers 2.5.4 (3.0.4 available)
  build_runner 2.5.4 (2.15.0 available)
  build_runner_core 9.1.2 (9.3.2 available)
  built_value 8.12.4 (8.12.6 available)
  code_assets 1.0.0 (1.2.1 available)
  connectivity_plus 7.1.1 (7.2.0 available)
  dart_style 3.1.1 (3.1.9 available)
  dart_webrtc 1.8.0 (1.8.1 available)
  dbus 0.7.12 (0.7.14 available)
  device_info_plus 12.3.0 (13.2.0 available)
  device_info_plus_platform_interface 7.0.3 (8.1.0 available)
  hooks 1.0.2 (2.0.2 available)
  json_annotation 4.9.0 (4.12.0 available)
  json_serializable 6.9.5 (6.14.0 available)
  matcher 0.12.19 (0.12.20 available)
  meta 1.18.0 (1.18.3 available)
  mockito 5.4.6 (5.7.0 available)
  native_toolchain_c 0.17.6 (0.19.2 available)
  objective_c 9.3.0 (9.4.1 available)
  package_config 2.2.0 (3.0.0 available)
  path_provider 2.1.5 (2.1.6 available)
  path_provider_android 2.2.22 (2.3.1 available)
  path_provider_linux 2.2.1 (2.2.2 available)
  path_provider_platform_interface 2.1.2 (2.1.3 available)
  source_gen 2.0.0 (4.2.3 available)
  source_helper 1.3.7 (1.3.12 available)
  synchronized 3.4.0 (3.4.1 available)
  test_api 0.7.11 (0.7.13 available)
  vector_math 2.2.0 (2.4.0 available)
  vm_service 15.0.2 (15.2.0 available)
  win32 5.15.0 (6.3.0 available)
  win32_registry 2.1.0 (3.0.3 available)
  xml 6.6.1 (7.0.1 available)
Got dependencies!
37 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Resolving dependencies in `./example`...
Downloading packages...
Got dependencies in `./example`.
Omitting pub get (package config already present)
Analyzing /tmp/LUTAEA
Omitting pub get (package config already present)
Analyzing .
Cleaning up
Cleaning up
Checking Package version
ignoring prerelease
-- Generating report using: Console Reporter --
BREAKING CHANGES
├── Field "kRpcVesion" removed (CF01)
└─┬ Class Participant
  └── Field "clientProtocol" added (required) (CF02)
Non-Breaking changes
├── Interface "ClientProtocolVersion" added (CI02) (minor)
├── Interface "ClientProtocolVersionExt" added (CI02) (minor)
├── Field "kRpcVesion" added (CF02) (minor)
├── Field "kRpcVersion" added (CF02) (minor)
├── Field "kRpcRequestTopic" added (CF02) (minor)
├── Field "kRpcResponseTopic" added (CF02) (minor)
├── Field "kRpcAttrRequestId" added (CF02) (minor)
├── Field "kRpcAttrMethod" added (CF02) (minor)
├── Field "kRpcAttrResponseTimeoutMs" added (CF02) (minor)
├── Field "kRpcAttrVersion" added (CF02) (minor)
├── Field "kRpcRequestVersionV2" added (CF02) (minor)
├─┬ Class ConnectOptions
│ ├── Field "clientProtocolVersion" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "clientProtocolVersion" added (CE02) (minor)
├─┬ Class RemoteParticipant
│ └── Field "clientProtocol" added (CF02) (minor)
└─┬ Class LocalParticipant
  └── Field "clientProtocol" added (CF02) (minor)
To learn more about the detected changes visit: https://github.com/bmw-tech/dart_apitool/blob/main/readme/change_codes.md
Version Check
New Version is too low!

Old version: "2.8.0"
New version: "2.8.0"
Needed version: "3.0.0"

Got "2.8.0" expected >= "3.0.0" (breaking changes)

If this is intentional, please add a changeset with major level in .changes/:

major type="changed" "Description of breaking change"

@1egoman

1egoman commented May 15, 2026

Copy link
Copy Markdown
Contributor Author

^ In the above "breaking change" warning, it looks like the issue is:

BREAKING CHANGES
└─┬ Class Participant
  └── Field "clientProtocol" added (required) (CF02)

But it's a field addition... That shouldn't be a breaking change? Let me know what I am missing - I could I think make this private, but I'd need to verify that is ok first.

Comment thread lib/src/rpc/rpc_client_manager.dart Outdated
Comment thread test/core/rpc_test.dart
Comment on lines 26 to 35
E2EContainer? container;
late Room room;

group('rpc tests', () {
test('test rpc handler register', () async {
container = E2EContainer();
room = container!.room;
await container!.connectRoom();

room.registerRpcMethod('echo', (RpcInvocationData data) async {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

question: Heads up that I kept all the old / pre-existing rpc v1 tests around. I'm not sure though if this is really still needed, because the new tests should be testing all the same paths. I'll defer to what others think here, I don't have a strong opinion on if they should be kept or removed.

@1egoman
1egoman marked this pull request as ready for review May 15, 2026 20:46

@xianshijing-lk xianshijing-lk left a comment

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.

some nits / questions

Comment thread example/lib/widgets/rpc_test_sheet.dart Outdated
Comment thread example/lib/widgets/rpc_test_sheet.dart Outdated
Comment thread example/lib/widgets/rpc_test_sheet.dart Outdated
Comment thread example/lib/widgets/rpc_test_sheet.dart
Comment thread lib/src/core/room.dart Outdated
Comment thread lib/src/core/room.dart Outdated
Comment thread lib/src/participant/participant.dart Outdated
/// `ParticipantInfo.clientProtocol`. Drives the caller- and handler-side decision
/// between RPC v1 packets and RPC v2 data streams. Absent / unrecognized values
/// from older clients resolve to `0` (matches [ClientProtocolVersion.v0]).
int get clientProtocol => _participantInfo?.clientProtocol ?? ClientProtocolVersion.v0.toIntValue();

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.

Just want to make sure I understand, this _participantInfo is the remote participant info, right ?

Comment thread lib/src/rpc/rpc_client_manager.dart Outdated
Comment thread lib/src/rpc/rpc_client_manager.dart Outdated
throw RpcError(code: RpcError.sendFailed, message: 'No local participant');
}

final writer = await local.streamText(StreamTextOptions(

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.

can you tell me where this streamText() is implemented ? local_participant.dart ?

Attach the RPC test controller to the active room instead of passing a room through each handler registration. Clear stale handlers when the sheet moves to another room, avoid registering against disposed rooms, and let handler card text use the theme's default text colors.
# Conflicts:
#	lib/src/participant/local.dart
Add caller-side RPC v2 coverage for legacy v1 fallback, pre-publish payload rejection, fast ack/response handling, and malformed response streams without request IDs.
@hiroshihorie
hiroshihorie merged commit fce3252 into main Jun 30, 2026
17 checks passed
@hiroshihorie
hiroshihorie deleted the add-rpc-v2 branch June 30, 2026 09:19
rokk4 added a commit to rokk4/client-sdk-flutter that referenced this pull request Jul 28, 2026
Brings 18 upstream commits, notably 42f6b14 "fix: allow selectAudioOutput on
Android" (livekit#1121) — without it Hardware.selectAudioOutput early-returned with
"only supported on Desktop", so the in-call output picker was inert on Android.
selectAudioOutput now refuses only on Web/iOS.

Conflict resolution:

- lib/src/options.dart — both sides added a RoomOptions field in the same place.
  Kept both: our pendingTrackQueueMaxSize and upstream's networkOptions.
- lib/src/core/room.dart — kept our prefixed pending_queue.PendingTrackQueue
  construction (metadataTimeout, not upstream's ttl) and added upstream's
  RpcClientManager/RpcServerManager init from the RPC v2 work (livekit#1087).

Dropped the VP9 patch (cffd8a7 "vp9 experiment"):

  web/e2ee.frame_cryptor.dart is restored to upstream. That patch made
  getUnencryptedBytes return 0 for VP9 — encrypt the whole frame, header
  included — while every other peer (native libwebrtc, the JS SDK) uses the
  standard key=10 / delta=3 prefix. Since the same function runs on both
  encrypt and decrypt, the mismatch means a VP9 frame from mobile cannot be
  decrypted on web and vice versa, and with failureTolerance: -1 it fails
  silently rather than surfacing an error.

  It is also redundant: upstream fixed VP9 E2EE properly in b835995 (livekit#953),
  which narrowed the frame-cryptor skip from isSVCCodec to isAV1Codec, and
  that fix is already in this branch. Our patch predates it by a month and
  targeted the same symptom via the wrong mechanism.

Verified: flutter analyze clean, all 70 tests in test/core pass, and the three
patches the fork exists for are intact (pending_track_queue rejoin hardening,
pendingTrackQueueMaxSize, iOS podspec 16.0).
hiroshihorie added a commit that referenced this pull request Jul 28, 2026
The RPC tester itself landed on main through #1087, which included a
hardened copy of this branch's rpc_test_sheet.dart and the controls.dart
wiring. Resolve the add/add conflict by taking main's version, so this
branch now carries only follow-up fixes.
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.

3 participants