Return a PublishDataInstruction from PublishData#301
Conversation
xianshijing-lk
left a comment
There was a problem hiding this comment.
some nits / questions
| /// Check <see cref="YieldInstruction.IsError"/> and read <see cref="PublishDataInstruction.Error"/> | ||
| /// to handle the result (e.g. payloads exceeding the negotiated maximum message size). | ||
| /// </returns> | ||
| public PublishDataInstruction PublishData(byte[] data, IReadOnlyCollection<string> destination_identities = null, bool reliable = true, string topic = null) |
There was a problem hiding this comment.
Instruction does not seem to be a common technology for such purpose ?
how about PublishDataTask ?
There was a problem hiding this comment.
We use the instruction term since the base type is CustomYieldInstruction
Other examples in our code base:
There was a problem hiding this comment.
Instructions use Coroutines underneath, Tasks use C# async
There was a problem hiding this comment.
I see. Thanks for the context
| IsDone = true; | ||
| } | ||
|
|
||
| void OnCanceled() |
There was a problem hiding this comment.
nit, should onCanceled() private ?
There was a problem hiding this comment.
It is private by default, and we also use the implicit private style around in the other instruction classes:
LocalParticipant.PublishData is fire-and-forget — the C# API has no callback, so server-side drops of oversized packets are silent. These tests probe the boundary empirically by publishing payloads of varying sizes between two participants and asserting delivery via the subscriber's DataReceived event. Retries on a 200 ms interval to avoid SFU warm-up flakiness. Verified against livekit-server 1.12.0: 1 KiB and 15 KiB arrive intact (length + bytes); 65 KiB is dropped. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PublishData was fire-and-forget (void), so callers could not tell whether
the Rust side accepted the packet. The FFI transport already carried the
result end-to-end — PublishDataRequest has a request_async_id, Rust emits
a PublishDataCallback { async_id, error }, and the data_task forwards the
publish result into it — but the C# side discarded the event.
Wire it through:
- New PublishDataInstruction (YieldInstruction) exposing IsError + Error.
- The three PublishData overloads now return it instead of void
(source-compatible: callers ignoring the result still compile).
- Route the callback by adding PublishData to FFIClient.ExtractRequestAsyncId.
Packets over the negotiated maximum message size now surface the error
("data packet size (N bytes) exceeds the negotiated maximum message size
(64000 bytes)") via instruction.Error.
Tests: ReturnsSuccess_ForSmallPayload verifies the success path on any
binary. ReturnsError_ForOversizedPayload (Explicit) verifies the size-limit
error and requires the client-sdk-rust datamessage_size FFI binary.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2f0c618 to
a037797
Compare
| /// Check <see cref="YieldInstruction.IsError"/> and read <see cref="PublishDataInstruction.Error"/> | ||
| /// to handle the result (e.g. payloads exceeding the negotiated maximum message size). | ||
| /// </returns> | ||
| public PublishDataInstruction PublishData(byte[] data, IReadOnlyCollection<string> destination_identities = null, bool reliable = true, string topic = null) |
There was a problem hiding this comment.
I see. Thanks for the context
Dependency
Depends on livekit/rust-sdks#1137
Fails without: https://github.com/livekit/client-sdk-unity/actions/runs/27275793150
Summary
LocalParticipant.PublishDatawas fire-and-forget (void), so callers had no way to know whether the Rust side accepted the packet — most importantly, packets exceeding the negotiated maximum message size were dropped with only alog::warn!.This wires through the result the FFI transport already carried (no proto regen, no Rust changes):
PublishDataRequestalready hasrequest_async_id; Rust already emitsPublishDataCallback { async_id, error }anddata_taskforwards the publish result into it. The C# side simply discarded the event.Changes:
PublishDataInstruction(YieldInstruction) exposingIsError+Error.PublishDataoverloads now return it instead ofvoid(source-compatible — callers ignoring the result still compile).PublishDatatoFFIClient.ExtractRequestAsyncId.Oversized packets now surface the error via
instruction.Error:Tests
ReturnsSuccess_ForSmallPayload— verifies the success path; runs on any FFI binary.ReturnsError_ForOversizedPayload— verifies the size-limit error. Marked[Explicit]: it requires theclient-sdk-rustdatamessage_sizeFFI binary that enforces the 64000-byte limit (shipped plugins do not yet). Against the old binary an oversized reliable send wedges the publisher transport instead of returning cleanly — which is the behavior the limit fixes.Verified locally: all 2
PublishDataTestspass (3.3s) against a macOS FFI lib rebuilt fromdatamessage_size+livekit-server --dev.