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";
2
3const app = createApp({ port: 3000 });
4const wss = createWebSocketServer({ path: "/ws" });
5
6// Handle new connections
7wss.onOpen((ws) => {
8 console.log("Client connected:", ws.data.id);
9 ws.send(JSON.stringify({ type: "welcome", id: ws.data.id }));
10});
11
12// Handle disconnections
13wss.onClose((ws) => {
14 console.log("Client disconnected:", ws.data.id);
15});
16
17// Handle messages
18wss.on("message", (ws, message) => {
19 console.log("Received:", message);
20});
21
22app.listen();

Event Handling

events.ts
1// Register event handlers
2wss.on("chat:message", async (ws, message) => {
3 const data = JSON.parse(message);
4
5 // Broadcast to room
6 wss.broadcastToRoom("chat", {
7 event: "chat:message",
8 data: {
9 userId: ws.data.userId,
10 text: data.text,
11 timestamp: Date.now()
12 }
13 });
14});
15
16wss.on("user:typing", (ws, message) => {
17 wss.broadcastToRoom("chat", {
18 event: "user:typing",
19 data: { userId: ws.data.userId }
20 }, [ws.data.id]); // exclude sender
21});

Rooms

rooms.ts
1// Join a room
2wss.on("room:join", (ws, message) => {
3 const { roomName } = JSON.parse(message);
4 wss.joinRoom(ws, roomName);
5
6 // Notify others
7 wss.broadcastToRoom(roomName, {
8 event: "user:joined",
9 data: { userId: ws.data.id }
10 }, [ws.data.id]);
11});
12
13// Leave a room
14wss.on("room:leave", (ws, message) => {
15 const { roomName } = JSON.parse(message);
16 wss.leaveRoom(ws, roomName);
17
18 wss.broadcastToRoom(roomName, {
19 event: "user:left",
20 data: { userId: ws.data.id }
21 });
22});
23
24// Get room clients
25const clients = wss.getRoomClients("chat");
26console.log(`${clients.length} users in chat`);

Broadcasting

broadcast.ts
1// Broadcast to all clients
2wss.broadcast({ type: "announcement", text: "Hello everyone!" });
3
4// Broadcast to specific room
5wss.broadcastToRoom("game-123", { type: "game:update", state: gameState });
6
7// Send to specific client
8wss.sendTo(clientId, { type: "private", data: "secret" });
9
10// 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 user
2wss.on("auth", async (ws, message) => {
3 const { token } = JSON.parse(message);
4
5 try {
6 const user = await verifyToken(token);
7 wss.setUserId(ws, user.id);
8
9 // Join user's personal room
10 wss.joinRoom(ws, `user:${user.id}`);
11
12 ws.send(JSON.stringify({ event: "auth:success", data: user }));
13 } catch (error) {
14 ws.send(JSON.stringify({ event: "auth:error" }));
15 }
16});
17
18// Find all connections for a user
19const userSockets = wss.findByUserId(123);
20
21// Send notification to specific user
22wss.emit("notification", { text: "Hello!" }, `user:123`);

Client-Side

client.js
1// Client-side JavaScript
2const ws = new WebSocket("ws://localhost:3000/ws");
3
4ws.onopen = () => {
5 console.log("Connected!");
6
7 // Authenticate
8 ws.send(JSON.stringify({ event: "auth", data: { token: authToken } }));
9
10 // Join a room
11 ws.send(JSON.stringify({ event: "room:join", data: { roomName: "chat" } }));
12};
13
14ws.onmessage = (event) => {
15 const { event: eventName, data } = JSON.parse(event.data);
16
17 switch (eventName) {
18 case "chat:message":
19 displayMessage(data);
20 break;
21 case "user:typing":
22 showTypingIndicator(data.userId);
23 break;
24 }
25};
26
27// Send chat message
28function sendMessage(text) {
29 ws.send(JSON.stringify({ event: "chat:message", data: { text } }));
30}

Next Steps

Learn about securing your application.