package-lock.json
+5
-21
diff --git a/package-lock.json b/package-lock.json
index bcf0edd..d6ccb65 100644
@@ -9,9 +9,7 @@
"version": "0.0.1",
"dependencies": {
"express": "^5.2.1",
"nanoid": "^5.1.6",
"socket.io": "^4.8.3",
"socket.io-client": "^4.8.3"
"socket.io": "^4.8.3"
},
"devDependencies": {
"@sveltejs/adapter-node": "^5.4.0",
@@ -19,6 +17,7 @@
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"concurrently": "^9.2.1",
"prettier": "^3.7.4",
"socket.io-client": "^4.8.3",
"svelte": "^5.45.6",
"svelte-check": "^4.3.4",
"typescript": "^5.9.3",
@@ -1520,6 +1519,7 @@
"version": "6.6.4",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.4.tgz",
"integrity": "sha512-+kjUJnZGwzewFDw951CDWcwj35vMNf2fcj7xQWOctq1F2i1jkDdVvdFG9kM/BEChymCH36KgjnW0NsL58JYRxw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
@@ -2145,24 +2145,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/nanoid": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz",
"integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.js"
},
"engines": {
"node": "^18 || >=20"
}
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -2724,6 +2706,7 @@
"version": "4.8.3",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz",
"integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
@@ -3152,6 +3135,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
"dev": true,
"engines": {
"node": ">=0.4.0"
}
package.json
+2
-3
diff --git a/package.json b/package.json
index 53a2e40..fb11e3e 100644
@@ -21,6 +21,7 @@
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"concurrently": "^9.2.1",
"prettier": "^3.7.4",
"socket.io-client": "^4.8.3",
"svelte": "^5.45.6",
"svelte-check": "^4.3.4",
"typescript": "^5.9.3",
@@ -28,8 +29,6 @@
},
"dependencies": {
"express": "^5.2.1",
"nanoid": "^5.1.6",
"socket.io": "^4.8.3",
"socket.io-client": "^4.8.3"
"socket.io": "^4.8.3"
}
}
server.js
+0
-133
diff --git a/server.js b/server.js
deleted file mode 100644
index 05b681b..0000000
@@ -1,133 +0,0 @@
import { createServer } from "http";
import { Server } from "socket.io";
import { nanoid } from "nanoid";
const httpServer = createServer();
const io = new Server(httpServer, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});
// Room state management
const rooms = new Map();
// Map of socket IDs to room codes
const socketToRoom = new Map();
// Generate a unique 6-character room code
function generateRoomCode() {
let code;
do {
code = nanoid(6).toUpperCase();
} while (rooms.has(code));
return code;
}
io.on("connection", (socket) => {
console.log("Client connected:", socket.id);
// Master creates a room
socket.on("create-room", (callback) => {
const roomCode = generateRoomCode();
rooms.set(roomCode, {
master: socket.id,
displays: [],
createdAt: Date.now(),
});
socketToRoom.set(socket.id, roomCode);
socket.join(roomCode);
console.log(`Room created: ${roomCode} by ${socket.id}`);
callback({ success: true, roomCode });
});
// Display device joins a room
socket.on("join-room", (roomCode, callback) => {
const room = rooms.get(roomCode);
if (!room) {
callback({ success: false, error: "Room not found" });
return;
}
// Add display to room
room.displays.push(socket.id);
socketToRoom.set(socket.id, roomCode);
socket.join(roomCode);
// Notify master of new display
io.to(room.master).emit("display-joined", {
displayId: socket.id,
totalDisplays: room.displays.length,
});
console.log(`Display ${socket.id} joined room ${roomCode}`);
callback({ success: true, masterId: room.master });
});
// Game commands: master sends to specific display
socket.on("game-command", ({ to, command }) => {
io.to(to).emit("game-command", command);
});
// Game broadcast: master sends to all displays in room
socket.on("game-broadcast", ({ roomCode, command }) => {
const room = rooms.get(roomCode);
if (room) {
room.displays.forEach((displayId) => {
io.to(displayId).emit("game-command", command);
});
}
});
// Display actions: display sends to master
socket.on("display-action", (action) => {
const roomCode = socketToRoom.get(socket.id);
if (roomCode) {
const room = rooms.get(roomCode);
if (room) {
io.to(room.master).emit("display-action", {
from: socket.id,
action,
});
}
}
});
// Handle disconnections
socket.on("disconnect", () => {
console.log("Client disconnected:", socket.id);
const roomCode = socketToRoom.get(socket.id);
if (roomCode) {
const room = rooms.get(roomCode);
if (room) {
// If master disconnects, close the room
if (room.master === socket.id) {
console.log(`Master disconnected, closing room ${roomCode}`);
// Notify all displays
room.displays.forEach((displayId) => {
io.to(displayId).emit("room-closed");
socketToRoom.delete(displayId);
});
rooms.delete(roomCode);
} else {
// Remove display from room
room.displays = room.displays.filter((id) => id !== socket.id);
// Notify master
io.to(room.master).emit("display-left", {
displayId: socket.id,
totalDisplays: room.displays.length,
});
}
}
socketToRoom.delete(socket.id);
}
});
});
const PORT = process.env.PORT || 3001;
httpServer.listen(PORT, () => {
console.log(`Signaling server running on port ${PORT}`);
});
server/index.js
+5
-2
diff --git a/server/index.js b/server/index.js
index 13e1db1..df124d0 100644
@@ -2,7 +2,6 @@ import { handler } from "../build/handler.js";
import express from "express";
import { createServer } from "http";
import { Server } from "socket.io";
import { nanoid } from "nanoid";
// Create Express app and HTTP server
const app = express();
@@ -23,9 +22,13 @@ const socketToRoom = new Map();
// Generate a unique 6-character room code
function generateRoomCode() {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let code;
do {
code = nanoid(6).toUpperCase();
code = "";
for (let i = 0; i < 6; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
} while (rooms.has(code));
return code;
}