Spaces:
Sleeping
Sleeping
File size: 3,365 Bytes
9bff0af | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | const express = require("express");
const http = require("http");
const { Server } = require("socket.io");
const cors = require("cors");
const app = express();
app.use(cors());
app.use(express.json());
app.get("/health", (req, res) => res.json({ status: "ok", uptime: process.uptime() }));
const server = http.createServer(app);
const io = new Server(server, {
cors: { origin: "*", methods: ["GET", "POST"] },
});
const rooms = {};
function getRoom(roomId) {
if (!rooms[roomId]) {
rooms[roomId] = {
users: {},
canvasElements: [],
code: { content: "// Start coding together...\n", language: "javascript" },
messages: [],
};
}
return rooms[roomId];
}
io.on("connection", (socket) => {
let currentRoom = null;
let currentUser = null;
socket.on("join-room", ({ roomId, user }) => {
currentRoom = roomId;
currentUser = { ...user, socketId: socket.id };
socket.join(roomId);
const room = getRoom(roomId);
room.users[socket.id] = currentUser;
socket.emit("room-state", {
canvasElements: room.canvasElements,
code: room.code,
messages: room.messages,
users: Object.values(room.users),
});
socket.to(roomId).emit("user-joined", currentUser);
io.to(roomId).emit("room-users", Object.values(room.users));
console.log(`[${roomId}] ${user.name} joined`);
});
socket.on("canvas-elements", (elements) => {
if (!currentRoom) return;
rooms[currentRoom].canvasElements = elements;
socket.to(currentRoom).emit("canvas-elements", elements);
});
socket.on("canvas-clear", () => {
if (!currentRoom) return;
rooms[currentRoom].canvasElements = [];
io.to(currentRoom).emit("canvas-clear");
});
socket.on("code-change", ({ content, language }) => {
if (!currentRoom) return;
rooms[currentRoom].code = { content, language };
socket.to(currentRoom).emit("code-update", { content, language });
});
socket.on("cursor-move", ({ x, y }) => {
if (!currentRoom || !currentUser) return;
socket.to(currentRoom).emit("cursor-update", {
socketId: socket.id,
name: currentUser.name,
color: currentUser.color,
x,
y,
});
});
socket.on("send-message", (msg) => {
if (!currentRoom) return;
const fullMsg = { ...msg, id: Date.now().toString() };
rooms[currentRoom].messages.push(fullMsg);
if (rooms[currentRoom].messages.length > 200) {
rooms[currentRoom].messages = rooms[currentRoom].messages.slice(-200);
}
io.to(currentRoom).emit("receive-message", fullMsg);
});
socket.on("disconnect", () => {
if (!currentRoom) return;
const room = rooms[currentRoom];
if (!room) return;
delete room.users[socket.id];
io.to(currentRoom).emit("user-left", socket.id);
io.to(currentRoom).emit("room-users", Object.values(room.users));
if (Object.keys(room.users).length === 0) {
setTimeout(() => {
if (rooms[currentRoom] && Object.keys(rooms[currentRoom].users).length === 0) {
delete rooms[currentRoom];
console.log(`[${currentRoom}] Room closed (empty)`);
}
}, 300000);
}
console.log(`[${currentRoom}] ${currentUser?.name || socket.id} left`);
});
});
const PORT = process.env.PORT || 3001;
server.listen(PORT, () => console.log(`Canvas2Code server running on :${PORT}`));
|