-
Notifications
You must be signed in to change notification settings - Fork 2
TokenSource API examples #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
17d2cc7
Remove second arg init
alan-george-lk f7ad2e0
Add token_source examples
alan-george-lk 93c960d
Latest header
alan-george-lk 6876b08
Prefix token_source example files; pin SDK commit
alan-george-lk 677fb78
Update token source examples for create factories
alan-george-lk 3424acc
Fetch token credentials before connecting
alan-george-lk 4c5b55c
Merge branch 'main' of github.com:livekit-examples/cpp-example-collec…
alan-george-lk a045d9b
Doc updates
alan-george-lk 6ea57b0
More README updates
alan-george-lk d84d1bd
Additional readme
alan-george-lk 1a4f31f
Scale back README updates
alan-george-lk 49b4e2d
Merge branch 'main' of github.com:livekit-examples/cpp-example-collec…
alan-george-lk 9076bc9
Update README
alan-george-lk f5c5175
PR feedback
alan-george-lk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # Copyright 2026 LiveKit, Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # One executable per token source type. Each shares token_source_common.h for | ||
| # the logging delegate and the connect/observe session loop. | ||
|
|
||
| # Resolve the SDK lib directory so -llivekit_ffi is found at link time. | ||
| get_filename_component(_lk_cmake_dir "${LiveKit_DIR}" DIRECTORY) # .../lib/cmake | ||
| get_filename_component(_lk_lib_dir "${_lk_cmake_dir}" DIRECTORY) # .../lib | ||
|
|
||
| set(_token_source_examples | ||
| token_source_literal token_source_literal.cpp | ||
| token_source_endpoint token_source_endpoint.cpp | ||
| token_source_sandbox token_source_sandbox.cpp | ||
| token_source_custom token_source_custom.cpp | ||
| token_source_caching token_source_caching.cpp | ||
| ) | ||
|
|
||
| list(LENGTH _token_source_examples _count) | ||
| math(EXPR _last "${_count} - 1") | ||
| foreach(_i RANGE 0 ${_last} 2) | ||
| list(GET _token_source_examples ${_i} _target) | ||
| math(EXPR _src_idx "${_i} + 1") | ||
| list(GET _token_source_examples ${_src_idx} _src) | ||
|
|
||
| add_executable(${_target} ${_src}) | ||
| target_include_directories(${_target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| target_link_libraries(${_target} PRIVATE ${LIVEKIT_CORE_TARGET}) | ||
| target_link_directories(${_target} PRIVATE "${_lk_lib_dir}") | ||
|
|
||
| livekit_copy_windows_runtime_dlls(${_target}) | ||
| endforeach() | ||
|
|
||
| unset(_token_source_examples) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| # Token Source Examples | ||
|
|
||
| These examples show the different ways to obtain the credentials | ||
| (**WebSocket URL** + **participant JWT**) the SDK needs to join a room. Each | ||
|
alan-george-lk marked this conversation as resolved.
|
||
| example builds its own executable, constructs a single kind of | ||
| [`TokenSource`](https://github.com/livekit/client-sdk-cpp/blob/main/include/livekit/token_source.h), | ||
| connects to a room, logs participant join/leave for a few seconds, then | ||
| disconnects. | ||
|
|
||
| > Token sources are for the **initial connection only**. Once connected, the | ||
| > LiveKit server refreshes the session token internally — your token source is | ||
| > not called again unless you connect again. See the SDK's | ||
| > [authentication docs](https://github.com/livekit/client-sdk-cpp/blob/main/docs/authentication.md). | ||
|
|
||
| ## Types | ||
|
|
||
| | Type | Example | When to use | | ||
| | --- | --- | --- | | ||
| | `LiteralTokenSource` | `token_source_literal.cpp` | You already have a URL + JWT (minted out of band, e.g. `lk token create`). The SDK consumes them as-is. | | ||
| | `EndpointTokenSource` | `token_source_endpoint.cpp` | Recommended for production. The SDK POSTs request options to your backend token endpoint, which returns the URL + a fresh JWT. API keys stay server-side. | | ||
| | `SandboxTokenSource` | `token_source_sandbox.cpp` | Local development only. Uses LiveKit Cloud's sandbox token server. **Not for production.** | | ||
| | `CustomTokenSource` | `token_source_custom.cpp` | You have an internal auth/token system. Plug in your own async callback that returns credentials. | | ||
| | `CachingTokenSource` | `token_source_caching.cpp` | A decorator that adds JWT-aware caching around any configurable source (endpoint/sandbox/custom) to cut down on fetch calls. | | ||
|
|
||
| `LiteralTokenSource` is *fixed* (no per-call options); the others are | ||
| *configurable* and accept | ||
| [`TokenRequestOptions`](https://github.com/livekit/client-sdk-cpp/blob/main/include/livekit/token_source.h) | ||
| (room name, participant identity, agent dispatch, ...). | ||
|
|
||
| ## Configuring the Examples | ||
|
|
||
| All inputs come from environment variables, so no secrets or sandbox IDs are committed to source. | ||
|
|
||
| | Variable | Used by | Notes | | ||
| | --- | --- | --- | | ||
| | `LIVEKIT_URL` | literal, custom | WebSocket URL, e.g. `ws://localhost:7880`. | | ||
| | `LIVEKIT_TOKEN` | literal, custom | Participant JWT. | | ||
| | `LIVEKIT_TOKEN_ENDPOINT` | endpoint, caching | Token endpoint URL. Default `http://127.0.0.1:3000/createToken`. | | ||
| | `LIVEKIT_TOKEN_ENDPOINT_METHOD` | endpoint, caching | Optional HTTP method (default `POST`). | | ||
| | `LIVEKIT_TOKEN_ENDPOINT_HEADERS` | endpoint, caching | Optional newline-separated `Name: Value` headers. | | ||
| | `LIVEKIT_SANDBOX_ID` | sandbox | Required. Sandbox ID from LiveKit Cloud. | | ||
| | `LIVEKIT_AGENT_NAME` | sandbox | Optional agent to dispatch into the room. | | ||
| | `LIVEKIT_AGENT_METADATA` | sandbox | Optional metadata for the dispatched agent. | | ||
|
|
||
| These examples require LiveKit C++ SDK **v1.3.0** or newer. Build them with the | ||
| rest of the repo — see the root [README](../README.md#building-the-examples). | ||
|
|
||
| ## Running the Examples | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| #### LiveKit Server | ||
|
|
||
| Start a development server via: | ||
|
|
||
| ```bash | ||
| livekit-server --dev | ||
| ``` | ||
|
|
||
| #### Token Sources | ||
|
|
||
| For literal and custom, generate a development token with the | ||
| [LiveKit CLI](https://docs.livekit.io/home/cli/cli-setup/) (a dev server started | ||
| with `livekit-server --dev` uses `devkey` / `secret`): | ||
|
|
||
| ```bash | ||
| export LIVEKIT_TOKEN=$(lk token create \ | ||
| --api-key devkey --api-secret secret \ | ||
| -i my-participant --join --room my-room \ | ||
| --valid-for 24h --token-only) | ||
| ``` | ||
|
|
||
| For the endpoint and caching examples, run a local token server such as | ||
| [token-server-node](https://github.com/livekit-examples/token-server-node). This can be run via: | ||
|
|
||
| ```bash | ||
| cd <path-to>/token-server-node | ||
| LIVEKIT_URL=ws://localhost:7880 LIVEKIT_API_KEY=devkey LIVEKIT_API_SECRET=secret PORT=3000 pnpm start | ||
| ``` | ||
|
|
||
| For sandbox, create a **Token Server** sandbox in [LiveKit Cloud](https://cloud.livekit.io) | ||
| (Sandbox → create from the token-server template), then copy the sandbox ID | ||
| (`token-server-xxxxxx`). See the | ||
| [sandbox token server docs](https://docs.livekit.io/frontends/build/authentication/sandbox-token-server/) | ||
| for setup details. Do not use this in production. | ||
|
|
||
| ```bash | ||
| export LIVEKIT_SANDBOX_ID=token-server-xxxxxx | ||
| # optional: dispatch a registered agent into the room with metadata | ||
| # export LIVEKIT_AGENT_NAME=my-agent | ||
| # export LIVEKIT_AGENT_METADATA='{"greeting": "hello from cpp"}' | ||
| ``` | ||
|
|
||
| ### Executing | ||
|
|
||
| The built binaries live under `build/token_source/`: | ||
|
|
||
| ```bash | ||
| # Literal: bring your own URL + token | ||
| export LIVEKIT_URL=ws://localhost:7880 | ||
| export LIVEKIT_TOKEN=<participant-jwt> | ||
| ./build/token_source/token_source_literal | ||
| ``` | ||
|
|
||
| ```bash | ||
| # Endpoint / caching: point at your token endpoint | ||
| export LIVEKIT_TOKEN_ENDPOINT=http://127.0.0.1:3000/createToken | ||
| ./build/token_source/token_source_endpoint | ||
| ./build/token_source/token_source_caching | ||
| ``` | ||
|
|
||
| ```bash | ||
| # Sandbox: development-only, ID from the environment | ||
| export LIVEKIT_SANDBOX_ID=<your-sandbox-id> | ||
| export LIVEKIT_AGENT_NAME=<your-agent-name> # optional | ||
| export LIVEKIT_AGENT_METADATA=<your-agent-metadata> # optional | ||
| ./build/token_source/token_source_sandbox | ||
| ``` | ||
|
|
||
| ```bash | ||
| # Custom: callback returns credentials (this example reads the env) | ||
| export LIVEKIT_URL=ws://localhost:7880 | ||
| export LIVEKIT_TOKEN=<participant-jwt> | ||
| ./build/token_source/token_source_custom | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| /* | ||
| * Copyright 2026 LiveKit, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| // Caching token source: a decorator that adds JWT-aware caching to any | ||
| // configurable token source (endpoint, sandbox, or custom). | ||
| // | ||
| // Repeated fetches for the same request options reuse the cached token until it | ||
| // nears expiry or you call invalidate() to drop the cached credentials, cutting | ||
| // down calls to your backend. This example wraps an EndpointTokenSource. | ||
| // | ||
| // Environment: | ||
| // LIVEKIT_TOKEN_ENDPOINT Token endpoint URL | ||
| // (default http://127.0.0.1:3000/createToken) | ||
| // LIVEKIT_TOKEN_ENDPOINT_METHOD Optional HTTP method (default POST) | ||
| // LIVEKIT_TOKEN_ENDPOINT_HEADERS Optional newline-separated "Name: Value" headers | ||
|
|
||
| #include <livekit/livekit.h> | ||
| #include <livekit/token_source.h> | ||
|
|
||
| #include <iostream> | ||
| #include <string> | ||
| #include <utility> | ||
|
|
||
| #include "token_source_common.h" | ||
|
|
||
| namespace { | ||
|
|
||
| using namespace token_source_example; | ||
|
|
||
| bool cachingTokenSourceConnect() { | ||
| std::string endpoint_url = getenvOrEmpty("LIVEKIT_TOKEN_ENDPOINT"); | ||
| if (endpoint_url.empty()) { | ||
| endpoint_url = "http://127.0.0.1:3000/createToken"; | ||
| } | ||
|
|
||
| std::cout << "Caching token source wrapping endpoint: " << endpoint_url << "\n"; | ||
|
|
||
| // Build the inner source, then wrap it. CachingTokenSource::create takes | ||
| // ownership of the inner source via unique_ptr. | ||
| auto inner = livekit::EndpointTokenSource::create(endpoint_url, endpointOptionsFromEnv()); | ||
| auto token_source = livekit::CachingTokenSource::create(std::move(inner)); | ||
|
|
||
| livekit::TokenRequestOptions request_options; | ||
| request_options.participant_identity = "robot-a"; | ||
| const auto credentials = token_source->fetch(request_options).get(); | ||
| if (!credentials) { | ||
| std::cerr << "Failed to fetch credentials: " << credentials.error().message << "\n"; | ||
| return false; | ||
| } | ||
|
|
||
| livekit::Room room; | ||
| ParticipantLogDelegate delegate; | ||
| room.setDelegate(&delegate); | ||
| if (!room.connect(credentials.value().server_url, credentials.value().participant_token, livekit::RoomOptions())) { | ||
| std::cerr << "Failed to connect to room\n"; | ||
| return false; | ||
| } | ||
| std::cout << "Connected to room: " << room.roomInfo().name << " (caching token source)\n"; | ||
|
|
||
| return runConnectedSession(room); | ||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
| int main() { | ||
| livekit::initialize(livekit::LogLevel::Info); | ||
| const bool ok = cachingTokenSourceConnect(); | ||
| livekit::shutdown(); | ||
| return ok ? 0 : 1; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.