Expand description
Stateroom is a minimalist framework for developing stateful WebSocket applications.
Stateroom apps implement the [SimpleStateroomService] trait, which provides a way for the app to hook into events when clients connect, disconnect, and send messages. Additionally, Stateroom provides a simple mechanism for invoking events in the future with a timer.
A simple chat server looks like this:
use stateroom::*;
use std::collections::HashMap;
#[derive(Default)]
struct ChatServer {
/// The server's only state is a mapping of client ID to username.
client_to_nickname: HashMap<ClientId, String>,
}
impl StateroomService for ChatServer {
/// This is called when a user connects.
fn connect(&mut self, client: ClientId, ctx: &impl StateroomContext) {
let username = format!("client{}", u32::from(client));
// Send a welcome message.
ctx.send_message(client,
format!("Welcome to the chat! Your name is {}. \
Send /nick <username> to change it.",
&username));
// Alert all other connected users to the new user.
ctx.send_message(MessageRecipient::Broadcast,
format!("{} has joined the chat", &username));
}
/// This is called when a user disconnects.
fn disconnect(&mut self, client: ClientId, ctx: &impl StateroomContext) {
let username = self.client_to_nickname.remove(&client).unwrap();
// Alert all remaining users that a user has left.
ctx.send_message(MessageRecipient::Broadcast,
format!("{} has left the chat", &username));
}
/// This is called when a user sends a message.
fn message(&mut self, client: ClientId, message: MessagePayload, ctx: &impl StateroomContext) {
let Some(message) = message.text() else {
// Ignore binary messages.
return;
};
if let Some(new_nick) = message.strip_prefix("/nick ") {
// This message is a /nick command, so process accordingly.
let old_nick = self.client_to_nickname.insert(client, new_nick.to_string()).unwrap();
ctx.send_message(MessageRecipient::Broadcast,
format!("{} is now known as {}", old_nick, new_nick));
} else {
// Broadcast the message to all connected users, prefixed by the username.
let username = self.client_to_nickname.get(&client).unwrap();
ctx.send_message(MessageRecipient::Broadcast,
format!("{}: {}", username, message));
}
}
}
Structs§
Enums§
- Represents the recipient(s) of a message.
Traits§
- Provides an interface for a StateroomService instance to send messages back to its host environment.
- A simplified interface for creating a StateroomService that can be exposed as a WebAssembly module.