This client enables you to use the following Supabase Realtime's features:
- Broadcast: Send ephemeral messages from client to clients with minimal latency. Use cases include sharing cursor positions between users.
- Presence: Track and synchronize shared ephemeral state across clients, such as who is currently online.
- Postgres Changes: Listen to database inserts, updates, and deletes and receive them on the client in real time.
- WebAssembly target (wasm32-unknown-unknown) supported
async fn main():
use supabase_realtime_rs::{
client::RealtimeClient,
types::{Result, SubscribeState},
};
const REALTIME_URL: &str = "http://127.0.0.1:54321";
const API_KEY: &str = "12345";
async fn main() -> Result<()> {
let mut client = RealtimeClient::new(REALTIME_URL, API_KEY, None, None, None)?;
let mut channel = client.create_channel("test-channel", None).await;
let on_subscribe = move |state_result: Result<SubscribeState>| match state_result {
Ok(state) => match state {
SubscribeState::Subscribed => {
println!("Conencted!");
}
SubscribeState::TimedOut => {
println!("Realtime server did not respond in time.");
}
SubscribeState::Closed => {
println!("Realtime channel was unexpectedly closed.");
}
},
Err(error) => {
eprintln!("There was an error subscribing to channel: {error}");
}
};
channel
.subscribe(&mut client, Some(Box::new(on_subscribe)))
.await?;
Ok(())
}REALTIME_URLishttp://127.0.0.1:54321when developing locally andwss://<project_ref>.supabase.co/realtime/v1when connecting to your Supabase project.API_KEYis a JWT whose claims must containexpandrole(existing database role).- Channel name can be any
string.
Your client can send and receive messages based on the event.
// Setup...
channel.on_broadcast("some-event", |payload| println!("{}", payload)).await;
let payload = Payload::Broadcast(Broadcast {
event: String::from("some-event"),
payload: json!({"message": format!("Hello world")}),
});
channel.send_broadcast(&client, "some-event", payload).await?;Your client can track its own presence and observe the presence state of everyone else on the channel.
// Setup...
channel.on_presence_sync(move || println!("Presence state changed")).await;
// Track the current user.
channel.track(&client, "123".into()).await?;
// Read the current presence state.
let state = channel.presence_state().await;
for (key, presence) in state.0 {
println!("{key}: {presence:?}");
}
// Stop tracking the current user.
channel.untrack(&client).await?;Your client can listen to inserts, updates, and deletes on a table.
// Setup...
channel
.on_postgres_changes(
JoinPostgresChangedEvent::All,
PostgresChangesParams::default()
.schema("public")
.table("todos"),
|payload| {
println!("{:?} on {}", payload.data.type_, payload.data.table);
if let Some(record) = payload.data.record {
println!("{record}");
}
},
)
.await?;- Register
on_postgres_changescallbacks before subscribing to the channel. Registering afterwards returnsRealtimeError::MultipleSubscriptionError. - Use
JoinPostgresChangedEvent::{Insert, Update, Delete}to listen to a single kind of change, andPostgresChangesParams::filterto narrow the rows you receive.
It is highly recommended that you clean up your channels after you're done with them.
- Remove a single channel
// Setup...
client.remove_channel(&channel).await?;- Remove all channels
// Setup...
client.remove_all_channels().await?;This repo is modeled after realtime-py but with some differences due to the constraints of rust.