Installation & Quick Start¶
This guide connects one Rust client, authenticates it, and joins a room. You need Rust 1.87.0 or newer, a Signal Fish server URL, and an app ID accepted by that server.
If you do not have a server yet, follow the Signal Fish Server five-minute quick start. Its development setup accepts a test app ID. The App ID is a public application label, not a secret. For production, use a label allowed by the server operator's policy.
Install the SDK¶
Add the client and the Tokio features used by this example:
The equivalent manifest entries are:
[dependencies]
signal-fish-client = "0.14.0"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
signal-fish-client enables its built-in WebSocket transport by default.
Published release and main
0.14.0 is the current crates.io release. This guide follows unreleased
main, which may include breaking APIs that have not reached a release
yet; the
changelog
says which release added them. Use the 0.14.0
docs.rs pages with the versioned
dependency above. To evaluate unreleased changes, use:
Connect and join a room¶
Create src/main.rs:
use signal_fish_client::{
JoinRoomParams, SignalFishClient, SignalFishConfig, SignalFishEvent,
WebSocketTransport,
};
#[tokio::main]
async fn main() -> Result<(), signal_fish_client::SignalFishError> {
let url = std::env::var("SIGNAL_FISH_URL")
.unwrap_or_else(|_| "ws://localhost:3536/v2/ws".to_owned());
let transport = WebSocketTransport::connect(&url).await?;
let config = SignalFishConfig::new("mb_app_abc123");
let (mut client, mut events) = SignalFishClient::start(transport, config);
while let Some(event) = events.recv().await {
match event {
SignalFishEvent::Connected => println!("transport connected"),
SignalFishEvent::Authenticated { app_name, .. } => {
println!("authenticated as {app_name}");
client.join_room(JoinRoomParams::new("my-game", "Alice"))?;
}
SignalFishEvent::RoomJoined { room_code, .. } => {
println!("joined room {room_code}");
}
SignalFishEvent::AuthenticationError { error, .. } => {
eprintln!("authentication failed: {error}");
break;
}
SignalFishEvent::Disconnected { reason, .. } => {
eprintln!("disconnected: {}", reason.as_deref().unwrap_or("unknown"));
break;
}
_ => {}
}
}
client.shutdown().await;
Ok(())
}
Replace mb_app_abc123 with your app ID, then run:
Authentication is queued when the client starts. Wait for Authenticated
before sending room commands, and keep receiving events for as long as the
client is active. A full event channel pauses protocol progress instead of
silently dropping events.
Add the game lifecycle¶
Most games continue with these events and commands:
- On
RoomJoined, callset_ready()once when the local player is ready (the wire message toggles readiness, so a second call would un-ready you). - Observe
LobbyStateChangedand authority events. - Call
start_game()once the server's room rules allow it. - Exchange JSON game data after
GameStarting. Binary frames require protocol v3 and an effectively negotiated binary format; see Game Data. - Handle reconnect or disconnect events and call
shutdown().awaiton exit.
The basic_lobby example
implements this flow without hiding authority changes or reconnect state. Run
the repository copy with:
Choose a different runtime¶
The async client runs a Tokio background task. Use the polling client when the host gives your code one callback per frame and does not continuously drive a Tokio runtime.
| Environment | Client and transport |
|---|---|
| Tokio native application | SignalFishClient + WebSocketTransport |
| Godot 4.5 native or web | SignalFishPollingClient + GodotWebSocketTransport |
| Browser with a custom binding | SignalFishPollingClient + your Transport |
| Custom async backend | SignalFishClient + your Transport + Send |
See WebAssembly for Godot and browser setup, or Transport to implement a backend.
Optional capabilities¶
The default feature set is enough for the example above. Add features only for the capability you need:
| Feature | Purpose |
|---|---|
transport-websocket |
Built-in native WebSocket transport; enabled by default |
tokio-runtime |
Async driver task, timing, and channel support; enabled by the default transport |
tls |
Native wss:// connections |
polling-client |
Caller-driven client for game loops |
mesh |
Protocol-v3 WebRTC mesh state and controller APIs |
token-binding |
Native Server 0.8 token-binding negotiation |
transport-websocket-emscripten |
Advanced custom Emscripten hosts |
The default transport-websocket feature also enables tokio-runtime, which
provides the task and timing support required by SignalFishClient. If you
disable default features, select both capabilities explicitly.
Next steps¶
- Basic Lobby Walkthrough for the complete lobby flow
- Client API Reference for commands and configuration
- Events Reference and Error Handling for event loops
- Protocol Versioning before enabling v3 or mesh
- Delivery Contract & Backpressure before tuning queue capacity