From 3de55ace964f2d3aaa3609db1cb2e91b15810c5c Mon Sep 17 00:00:00 2001 From: Max Heimbrock <43608204+MaxHeimbrock@users.noreply.github.com> Date: Tue, 9 Jun 2026 14:40:16 +0200 Subject: [PATCH] Document async/await + optional UniTask integration in the README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stage 4 (capstone) of the UniTask migration. Adds a README section covering the three interchangeable async styles the SDK now supports, and states the policy: coroutines remain the default and fully supported; async/await and UniTask are additive opt-ins; the coroutine API is not deprecated. - async/await with no dependency (instructions are awaitable; inspect IsError, await does not throw — parity with yield return). - UniTask opt-in (com.cysharp.unitask + LIVEKIT_UNITASK): AsUniTask with CancellationToken, UniTask.WhenAll composition, and AsAsyncEnumerable for await foreach over incremental streams (throws StreamError on error EoS). Examples use the verified public signatures (Connect(url, token, RoomOptions), PublishTrack(track, options), ReadIncremental().AsAsyncEnumerable()) and point to the Meet sample (UniTask) and Basic sample (coroutines) as references. Docs-only; no code, no deprecation, no version bump. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/README.md b/README.md index b72f1dde..d756a612 100644 --- a/README.md +++ b/README.md @@ -313,6 +313,62 @@ Debug.Log("Connected to " + room.Name); +### Asynchronous programming: coroutines, async/await, and UniTask + +The SDK exposes three interchangeable styles for awaiting asynchronous operations. **Coroutines (`yield return`) are the default and remain fully supported** — every other example in this README works unchanged. async/await and UniTask are purely additive opt-ins; the coroutine API is **not** deprecated. + +**1. Coroutines (default, no dependency)** — shown throughout this README. + +**2. async/await (no dependency)** — every operation returns an awaitable instruction (`ConnectInstruction`, `PublishTrackInstruction`, `PerformRpcInstruction`, the stream read instructions, …), so you can `await` it directly. As with coroutines, you inspect success/failure on the instruction (`IsError`) — `await` does not throw. Continuations resume on Unity's main thread. + +```cs +async void Start() +{ + var room = new Room(); + var connect = room.Connect("ws://localhost:7880", "", new RoomOptions()); + await connect; + if (!connect.IsError) + Debug.Log("Connected to " + room.Name); +} +``` + +> Use `async void` only for top-level event handlers (e.g. button callbacks); its exceptions surface to Unity's log rather than to a caller. Prefer `async Task`/`async UniTaskVoid` elsewhere. + +**3. UniTask (optional)** — install [UniTask](https://github.com/Cysharp/UniTask) (`com.cysharp.unitask`). The SDK auto-detects it via the `LIVEKIT_UNITASK` scripting define and enables the `LiveKit.UniTask` assembly, which adds `CancellationToken` support, composition, and async streams. + +Cancellation (abandon-awaiter semantics — the underlying request is not cancelled on the wire): + +```cs +await room.Connect("ws://localhost:7880", "", new RoomOptions()) + .AsUniTask(cancellationToken); +``` + +Run operations in parallel: + +```cs +await UniTask.WhenAll( + room.LocalParticipant.PublishTrack(cameraTrack, cameraOptions).AsUniTask(ct), + room.LocalParticipant.PublishTrack(microphoneTrack, microphoneOptions).AsUniTask(ct)); +``` + +Consume an incremental stream with `await foreach`. The sequence ends at end-of-stream; if the stream ends with an error it throws a `StreamError`: + +```cs +try +{ + await foreach (var chunk in reader.ReadIncremental().AsAsyncEnumerable(ct)) + Process(chunk); +} +catch (StreamError e) +{ + Debug.LogError(e.Message); +} +``` + +The **Meet** sample (`Samples~/Meet`) demonstrates the UniTask path end-to-end; the **Basic** sample stays on coroutines as the dependency-free reference. + + + ### Publishing microphone