Route awareness messages between peers
This commit is contained in:
parent
93bb462ffa
commit
56aa8dc9bd
3 changed files with 66 additions and 4 deletions
55
src/awareness.test.ts
Normal file
55
src/awareness.test.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { describe, test, expect, beforeAll, afterAll } from "bun:test";
|
||||
import type { Server } from "bun";
|
||||
|
||||
describe("awareness routing", () => {
|
||||
let server: Server;
|
||||
const PORT = 4042;
|
||||
|
||||
beforeAll(async () => {
|
||||
// Import and start server on test port
|
||||
process.env.PORT = String(PORT);
|
||||
const mod = await import("./index");
|
||||
server = mod.server;
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
server?.stop();
|
||||
});
|
||||
|
||||
test("awareness message routes to other peers in same room", async () => {
|
||||
const ws1 = new WebSocket(`ws://localhost:${PORT}/ws`);
|
||||
const ws2 = new WebSocket(`ws://localhost:${PORT}/ws`);
|
||||
|
||||
const received: unknown[] = [];
|
||||
|
||||
await Promise.all([
|
||||
new Promise(r => ws1.onopen = r),
|
||||
new Promise(r => ws2.onopen = r),
|
||||
]);
|
||||
|
||||
ws2.onmessage = (e) => {
|
||||
received.push(JSON.parse(e.data));
|
||||
};
|
||||
|
||||
// Both join same room
|
||||
ws1.send(JSON.stringify({ type: "join", room: "test" }));
|
||||
ws2.send(JSON.stringify({ type: "join", room: "test" }));
|
||||
|
||||
await Bun.sleep(50);
|
||||
|
||||
// ws1 sends awareness
|
||||
ws1.send(JSON.stringify({
|
||||
type: "awareness",
|
||||
data: { clientId: 1, cursor: { line: 10, col: 5 } }
|
||||
}));
|
||||
|
||||
await Bun.sleep(50);
|
||||
|
||||
const awareness = received.find(m => m.type === "awareness");
|
||||
expect(awareness).toBeDefined();
|
||||
expect(awareness.data.cursor).toEqual({ line: 10, col: 5 });
|
||||
|
||||
ws1.close();
|
||||
ws2.close();
|
||||
});
|
||||
});
|
||||
11
src/index.ts
11
src/index.ts
|
|
@ -14,7 +14,7 @@ function isValidRoomName(name: unknown): name is string {
|
|||
return /^[a-zA-Z0-9_-]+$/.test(name);
|
||||
}
|
||||
|
||||
Bun.serve<WsData>({
|
||||
export const server = Bun.serve<WsData>({
|
||||
port: PORT,
|
||||
fetch(req, server) {
|
||||
const url = new URL(req.url);
|
||||
|
|
@ -77,6 +77,15 @@ Bun.serve<WsData>({
|
|||
}
|
||||
break;
|
||||
}
|
||||
case "awareness": {
|
||||
if (ws.data.room) {
|
||||
const session = getSession(ws.data.room);
|
||||
if (session && "data" in msg) {
|
||||
session.broadcastAwareness(client, msg.data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
close(ws) {
|
||||
|
|
|
|||
|
|
@ -46,9 +46,7 @@ function isClientMessage(obj: unknown): obj is ClientMessage {
|
|||
Array.isArray(msg.data) && msg.data.every((n) => typeof n === "number")
|
||||
);
|
||||
case "awareness":
|
||||
return (
|
||||
Array.isArray(msg.data) && msg.data.every((n) => typeof n === "number")
|
||||
);
|
||||
return typeof msg.data === "object" && msg.data !== null;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue