use rustwave::{Result, Server};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct GameMessage {
mess: String,
room: String,
}
#[tokio::main]
async fn main() -> Result<()> {
let server = Server::bind("127.0.0.1:8080");
server.on("ping", |_, cx| async move {
let _ = cx.emit("pong", "accepted").await;
});
server.on("connection", |_data, ctx| async move {
println!("[root] client connected: {}", ctx.get_socket_id());
});
server.on("disconnect", |_data, ctx| async move {
println!("[root] client disconnected: {}", ctx.get_socket_id());
});
let chat = server.namespace("/chat");
chat.on("mess", |payload, cx| async move {
let _ = cx.emit("message", payload.raw()).await;
});
let game = server.namespace("game");
game.on("online-count", {
let game_ns = game.clone();
move |_data, ctx| {
let game_ns = game_ns.clone();
async move {
let count = game_ns.get_client_count();
let _ = ctx.emit("online-count", count).await;
}
}
});
game.on("typing", |payload, ctx| async move {
let room = payload.parse::<String>().unwrap_or_default();
let sender_id = ctx.get_socket_id();
let data = format!("user: {} type....", ctx.get_socket_id());
let _ = ctx
.broadcast_to_expect(&room, sender_id, "typing", data)
.await;
});
game.on("join-room", |payload, ctx| async move {
let room = payload.parse::<String>().unwrap_or_default();
if room.is_empty() {
return;
}
ctx.join_room(&room);
let _ = ctx
.broadcast_to_expect(
&room,
ctx.get_socket_id(),
"player-joined",
ctx.get_socket_id().to_string(),
)
.await;
});
game.on("leave-room", |payload, ctx| async move {
let room = payload.parse::<String>().unwrap_or_default();
if room.is_empty() {
return;
}
ctx.leave_room(&room);
let _ = ctx
.broadcast_to_expect(
&room,
ctx.get_socket_id(),
"player-left",
ctx.get_socket_id().to_string(),
)
.await;
});
game.on("mess", |payload, cx| async move {
let data = payload.parse::<GameMessage>().unwrap();
let _ = cx
.broadcast_to_expect(&data.room, cx.get_socket_id(), "mess", data.mess)
.await;
});
let admin = server.namespace("/admin");
admin.on("kick", {
let admin_ns = admin.clone();
move |payload, _ctx| {
let admin_ns = admin_ns.clone();
async move {
let target = payload.parse::<String>().unwrap_or_default();
if let Ok(target_id) = target.parse::<uuid::Uuid>() {
let _ = admin_ns.disconnect(&target_id).await;
}
}
}
});
admin.on("kick-all", {
let admin_ns = admin.clone();
move |_data, _ctx| {
let admin_ns = admin_ns.clone();
async move {
let _ = admin_ns.disconnect_all().await;
}
}
});
admin.on("is-online", {
let admin_ns = admin.clone();
move |payload, ctx| {
let admin_ns = admin_ns.clone();
async move {
let target = payload.parse::<String>().unwrap_or_default();
let online = target
.parse::<uuid::Uuid>()
.map(|id| admin_ns.is_connected(&id))
.unwrap_or(false);
let _ = ctx.emit("is-online", online).await;
}
}
});
println!("Listening on ws://127.0.0.1:8080");
server.run().await?;
Ok(())
}