Advanced
WebSockets
Full-duplex real-time communication with rooms, broadcasting, and event-based messaging.
Full Duplex
Bidirectional real-time communication
Rooms
Group clients into rooms for targeted messaging
Broadcasting
Send to all, rooms, or specific clients
Event-Based
Clean event handler pattern
Setting Up WebSocket Server
app.ts
1import { createApp, createWebSocketServer } from "canxjs";23const app = createApp({ port: 3000 });4const wss = createWebSocketServer({ path: "/ws" });56// Handle new connections7wss.onOpen((ws) => {8console.log("Client connected:", ws.data.id);9ws.send(JSON.stringify({ type: "welcome", id: ws.data.id }));10});1112// Handle disconnections13wss.onClose((ws) => {14console.log("Client disconnected:", ws.data.id);15});1617// Handle messages18wss.on("message", (ws, message) => {19console.log("Received:", message);20});2122app.listen();
Event Handling
events.ts
1// Register event handlers2wss.on("chat:message", async (ws, message) => {3const data = JSON.parse(message);45// Broadcast to room6wss.broadcastToRoom("chat", {7event: "chat:message",8data: {9userId: ws.data.userId,10text: data.text,11timestamp: Date.now()12}13});14});1516wss.on("user:typing", (ws, message) => {17wss.broadcastToRoom("chat", {18event: "user:typing",19data: { userId: ws.data.userId }20}, [ws.data.id]); // exclude sender21});
Rooms
rooms.ts
1// Join a room2wss.on("room:join", (ws, message) => {3const { roomName } = JSON.parse(message);4wss.joinRoom(ws, roomName);56// Notify others7wss.broadcastToRoom(roomName, {8event: "user:joined",9data: { userId: ws.data.id }10}, [ws.data.id]);11});1213// Leave a room14wss.on("room:leave", (ws, message) => {15const { roomName } = JSON.parse(message);16wss.leaveRoom(ws, roomName);1718wss.broadcastToRoom(roomName, {19event: "user:left",20data: { userId: ws.data.id }21});22});2324// Get room clients25const clients = wss.getRoomClients("chat");26console.log(`${clients.length} users in chat`);
Broadcasting
broadcast.ts
1// Broadcast to all clients2wss.broadcast({ type: "announcement", text: "Hello everyone!" });34// Broadcast to specific room5wss.broadcastToRoom("game-123", { type: "game:update", state: gameState });67// Send to specific client8wss.sendTo(clientId, { type: "private", data: "secret" });910// Emit event (auto-wraps in event structure)11wss.emit("notification", { message: "New message!" }, "user-room-456");
User Association
users.ts
1// Associate WebSocket with authenticated user2wss.on("auth", async (ws, message) => {3const { token } = JSON.parse(message);45try {6const user = await verifyToken(token);7wss.setUserId(ws, user.id);89// Join user's personal room10wss.joinRoom(ws, `user:${user.id}`);1112ws.send(JSON.stringify({ event: "auth:success", data: user }));13} catch (error) {14ws.send(JSON.stringify({ event: "auth:error" }));15}16});1718// Find all connections for a user19const userSockets = wss.findByUserId(123);2021// Send notification to specific user22wss.emit("notification", { text: "Hello!" }, `user:123`);
Client-Side
client.js
1// Client-side JavaScript2const ws = new WebSocket("ws://localhost:3000/ws");34ws.onopen = () => {5console.log("Connected!");67// Authenticate8ws.send(JSON.stringify({ event: "auth", data: { token: authToken } }));910// Join a room11ws.send(JSON.stringify({ event: "room:join", data: { roomName: "chat" } }));12};1314ws.onmessage = (event) => {15const { event: eventName, data } = JSON.parse(event.data);1617switch (eventName) {18case "chat:message":19displayMessage(data);20break;21case "user:typing":22showTypingIndicator(data.userId);23break;24}25};2627// Send chat message28function sendMessage(text) {29ws.send(JSON.stringify({ event: "chat:message", data: { text } }));30}