A Rust client library for Laravel Reverb WebSocket server. This library implements the Pusher protocol for real-time WebSocket communication.
- Channel Types: Support for public, private, and presence channels
- Authentication: Server-side HMAC authentication and client-side endpoint authentication
- Event Handling: Async trait-based event handlers for flexible event processing
- Automatic Keepalive: Built-in ping interval (30s) to maintain connection
- Automatic Reconnection: Detect disconnections with
wait_for_disconnect()for easy reconnection logic - TLS Support: Secure WebSocket connections via
wss://
Add to your Cargo.toml:
[dependencies]
reverb-rs = { git = "https://github.com/Team-Nifty-GmbH/reverb_rs" }use reverb_rs::{ReverbClient, EventHandler, private_channel};
use async_trait::async_trait;
use std::sync::Arc;
struct MyHandler {
client: Arc<ReverbClient>,
}
#[async_trait]
impl EventHandler for MyHandler {
async fn on_connection_established(&self, socket_id: &str) {
println!("Connected with socket ID: {}", socket_id);
// Subscribe to channels after connection is established
if let Err(e) = self.client.subscribe(private_channel("my-channel")).await {
eprintln!("Failed to subscribe: {}", e);
}
}
async fn on_channel_subscription_succeeded(&self, channel: &str) {
println!("Subscribed to channel: {}", channel);
}
async fn on_channel_event(&self, channel: &str, event: &str, data: &str) {
println!("Event {} on channel {}: {}", event, channel, data);
}
async fn on_error(&self, code: u32, message: &str) {
eprintln!("Error {}: {}", code, message);
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
loop {
let client = Arc::new(ReverbClient::new(
"your-app-key",
"your-app-secret",
"https://your-app.com/broadcasting/auth",
"your-reverb-host.com",
true, // use TLS (wss://)
));
let handler = MyHandler { client: client.clone() };
client.add_event_handler(handler).await;
match client.connect().await {
Ok(_) => {
println!("Connected to Reverb");
// Wait until the connection is closed
client.wait_for_disconnect().await;
println!("Connection lost");
}
Err(e) => {
eprintln!("Failed to connect: {}", e);
}
}
// Wait before reconnecting
println!("Reconnecting in 5 seconds...");
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
}
}No authentication required:
use reverb_rs::public_channel;
client.subscribe(public_channel("news")).await?;Requires authentication (automatically handled):
use reverb_rs::private_channel;
// The "private-" prefix is added automatically
client.subscribe(private_channel("user.123")).await?;For channels that track member presence:
use reverb_rs::presence_channel;
let user_data = serde_json::json!({
"user_id": 123,
"user_info": { "name": "John" }
}).to_string();
client.subscribe(presence_channel("chat-room", &user_data)).await?;When you provide an app_secret, the library authenticates using HMAC-SHA256:
let client = ReverbClient::new(
"app-key",
"app-secret", // Used for HMAC authentication
"https://app.com/broadcasting/auth",
"reverb.example.com",
true,
);If no secret is provided or for additional security, authentication is fetched from your Laravel endpoint:
let client = ReverbClient::new(
"app-key",
"", // Empty secret - will use endpoint auth
"https://your-app.com/broadcasting/auth",
"reverb.example.com",
true,
);Send events to channels (requires private or presence channel):
client.trigger_event(
"private-chat",
"typing", // Will be prefixed with "client-" automatically
serde_json::json!({ "user": "John" }),
).await?;client.unsubscribe("private-my-channel").await?;Use wait_for_disconnect() to block until the connection is closed (by server or network failure). This is useful for implementing reconnection logic:
loop {
let client = Arc::new(ReverbClient::new(/* ... */));
client.add_event_handler(handler).await;
if client.connect().await.is_ok() {
// Block until disconnection
client.wait_for_disconnect().await;
println!("Connection lost, reconnecting...");
}
tokio::time::sleep(Duration::from_secs(5)).await;
}Gracefully close the connection:
client.disconnect().await?;The library uses ReverbError for all error types:
use reverb_rs::ReverbError;
match client.connect().await {
Ok(_) => println!("Connected!"),
Err(ReverbError::WebSocketError(e)) => eprintln!("WebSocket error: {}", e),
Err(ReverbError::AuthError(msg)) => eprintln!("Auth failed: {}", msg),
Err(e) => eprintln!("Other error: {}", e),
}The library uses tracing for logging. Enable debug logs to see connection details:
tracing_subscriber::fmt()
.with_env_filter("reverb_rs=debug")
.init();- Rust 2024 edition
- Tokio runtime
- Laravel Reverb server (or any Pusher-compatible WebSocket server)
MIT License