reactor::Reactor is one session, and the tracks and commands on it. It speaks raw JSON over the
wire: open a session, send commands by name, receive generic message events. It works against any
model — for the commands and events a specific one accepts, see the
Model API Reference, or ask the running model itself with
request_schema().
std::future<T>, and failures arrive as exceptions from .get() — the same
typed hierarchy a synchronous call throws. See
ReactorError.
Movable, not copyable — a session has one owner. Destroying a connected client releases the native
handle, but a creator that goes away without
disconnect() leaves the session orphaned, and the
next run cannot start until it clears.Constructors
Signature
std::string
required
The model to connect to, as
owner/name. A bare name resolves under reactor/.ApiKey
An API key, exchanged for a session-scoped token when connecting. Scoped to this model, so a leak
is worth a handful of sessions rather than everything the key can reach.
Jwt
A token minted elsewhere, used as it is. For a server that already holds one, or a client handed
one by a backend that owns the key.
Options
Everything that is not the model or the credential — see below.
ApiKey and Jwt are distinct one-field structs rather than two std::string parameters, so the
credential you meant is the credential that is used:
Example
Options
Definition
std::string
default:"https://api.reactor.inc"
The coordinator.
reactor::LOCAL_API_URL is http://localhost:8080, for a local runtime.bool
default:"false"
Accept a dev coordinator’s self-signed certificate and speak its local-development protocol. Pair
it with
api_url = reactor::LOCAL_API_URL.Executor
Where control-event handlers run. Empty — the default — means the SDK’s own dispatcher thread.
Executor
Signature
Example
Futures do not go through the executor. A promise is settled on the library’s own completion
thread, so
connect().get() on the same thread that would have run the executor cannot deadlock
against it.Connecting
connect()
Creates — or adopts — a session and brings up the transport. Resolves when the session is
Ready.
Signature
Definition
std::optional<std::string>
Join a session that already exists rather than creating one. This is how a second client attaches
to the same session. A session adopted this way is not ended by
disconnect() — it keeps
running for its owner.std::optional<std::uint32_t>
Adopt a connection slot a backend already registered for this session. The connection-level
analogue of
session_id; most callers building one connection per session leave it unset. See
Multiple connections per session.UnauthorizedError for a token problem, ConflictError for a session a
previous run left orphaned.
Example
reconnect()
Cycles the connection without ending the session — after a transient failure, or deliberately from
Ready.
Signature
disconnect() first — and doing so
would end the very session this is about to reuse. Throws when there is no session to reconnect to.
RecvOnly tracks resume automatically. SendOnly tracks do not: a track published before the
reconnect is not published after it, so publish again for anything you were sending.
Track::published() says which side of that you are on, and
push_frame() throws rather than pushing into a slot with
nothing behind it.disconnect()
Ends the session server-side and tears down the transport.
Signature
reconnect(). Only ends sessions this client
created; one adopted via session_id is left running for its owner.
status()
Signature
Status. Readable before
connect() — a client that never connected reports Disconnected rather than nothing.
session_id()
Signature
Commands and uploads
send_command()
Sends a command to the model and waits for its correlated reply.
Signature
std::string
required
The command name. Must match a command the model defines.
Json
The payload.
reactor::Json is an alias for nlohmann::json.std::map<std::string, FileRef>
Files to pass as named parameters — see
upload_file().{type, data}, or empty when the handler ran and acknowledged the command without
returning a message, as an auto-generated set_<field> setter does. Empty is not a failure and is
not folded into one:
Example
.get() later — or drop
it, which sends the command all the same. These futures are settled by a promise rather than by
std::async, so dropping one neither blocks nor cancels; it only means a failure has nowhere to be
thrown.
upload_file()
Uploads a local file and returns a FileRef to pass into a
command.
Signature
Ready session — the upload is created against it. Throws NotFoundError when the path
does not exist.
Example
Uploads are passed separately rather than embedded in
args. The Python SDK finds a FileRef
sitting in the arguments and pulls it out; C++ has no way to recognise one inside a Json, so it
is named in the third parameter instead. Explicit costs a few characters and cannot silently miss
one.upload_bytes()
The same result as upload_file(), for a caller who has the bytes rather than a
path — a frame just rendered, a buffer just decoded.
Signature
data is borrowed for the call only.
Example
request_schema()
Signature
Recordings
request_clip()
Asks for a clip covering the last duration_seconds of the session.
Signature
Clip::download() is what waits for that.
Example
request_recording()
Signature
Tracks
track()
The track called name, as a Track — the only way to push frames into
one, receive its frames, or pause it.
Signature
Example
NotFoundError, listing what the session does declare, for a name that is not among them.
Before the session has declared anything, any name is allowed: there is nothing yet to contradict,
and the refusals that matter happen when a handler is registered or a frame is pushed.
tracks()
Every track the session declared, as a TrackList — for
discovery, and for a caller who would rather not hardcode a name.
Signature
Example
connect().
set_bitrate()
Bounds what the whole connection may allocate, in bits per second.
Signature
Definition
std::optional<std::int32_t>
A floor for the congestion controller; it will not drop below this even on a poor estimate. A
floor above what the link can sustain trades graceful degradation for a fixed send rate, so choose
it deliberately.
std::optional<std::int32_t>
The initial encoder target. WebRTC starts at ~300 kbps and ramps, which is visible as a few
seconds of soft video.
std::optional<std::int32_t>
A ceiling on the whole connection.
Ready. The bounds outlive a reconnect.
get_stats()
A snapshot of the live connection: RTT, jitter, packet loss, bitrates, the transport ICE selected,
and the WebRTC engine’s own per-stream counters.
Signature
ConnectionStats. Throws on a session that is
not Ready.
Example
Events
Everyon_* returns a Subscription: an RAII token that
unregisters the handler when it goes out of scope.
Signature
Example
on_message never has to filter the platform’s out of it.
There is no client-wide frame event. Media is delivered per track, through
Track::on_frame() and
Track::on_audio() — a single handler fed every incoming
track of a kind at once could not tell them apart.on_error hands you a ReactorError, the same type a failed call throws. Match on code(), or
branch on recoverable() when the specific code does not matter. See
ReactorError.time_micros()
The engine’s monotonic clock, in microseconds — the epoch a frame’s capture time is read in.
Signature
Example