Events reach the browser on the port you already serve.
Mark an event Broadcastable and it is pushed to public, private or presence channels. Rainier serves the WebSockets itself, on the HTTP port.
What you get
- Broadcast drivers: log, memory, Redis and Kafka.
- A native
WebSocketHandleron the same port as HTTP. pusher-server: an in-process Pusher-protocol server, so apusher-jsclient keeps working unchanged.- Private and presence channels authorised by your guard.
- Honest limit: rooms are per process — there are no clustered WebSocket rooms yet.
In the docs
src/app/models/post.rs
#[derive(Debug, Clone, Serialize)]
pub struct PostPublished {
pub post: Post,
}
impl Broadcastable for PostPublished {
fn broadcast_on(&self) -> Vec<BroadcastChannelName> {
vec![BroadcastChannelName::public("posts")]
}
fn broadcast_as(&self) -> String {
"post.published".into()
}
}
// Pushed to every browser subscribed to `posts` — over Rainier's own
// WebSocket server or its Pusher-protocol one, on the HTTP port.
events.listen(|event: Arc<PostPublished>| async move {
Broadcast::instance().event(event.as_ref()).await
});
src/routes/ws.rs
pub struct Chat {
rooms: Arc<Rooms>,
}
#[async_trait]
impl WebSocketHandler for Chat {
async fn on_connect(&self, socket: &Socket) -> Result<()> {
self.rooms.join("lobby", socket.clone());
socket.send("welcome")
}
async fn on_message(&self, socket: &Socket, message: Message) -> Result<()> {
self.rooms.send_except("lobby", socket.id(), message);
Ok(())
}
}
// On the same port as HTTP.
Rainier::new(".").with_websockets(WebSocketRoutes::new().add("/ws/rooms/{room}", Chat { rooms }))
Up close
Select an image to see it full size.