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.10.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.10.0 is the current crates.io release. This guide follows unreleased
main, which includes breaking APIs planned for 0.11. Use the 0.10.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()when the local player is ready. - 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 and timing 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.7 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