Spaces:
Paused
Paused
File size: 4,799 Bytes
abc1805 | 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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | const { createServer } = require("http");
const { Server } = require("socket.io");
const httpServer = createServer();
const io = new Server(httpServer, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});
// Track room users: RoomId -> UserId -> SocketCount
const roomUsers = new Map();
// Track room limits: RoomId -> Limit
const roomLimits = new Map();
// Track nicknames: SocketId -> Nickname
const socketNicknames = new Map();
io.on("connection", (socket) => {
console.log("Client connected:", socket.id);
const userId = socket.handshake.auth.userId;
if (!userId) {
console.log("No userId provided, ignoring");
return;
}
socket.on("join-room", async ({ roomId, nickname, userLimit }) => {
// Set limit if provided (room creation)
if (userLimit && !roomLimits.has(roomId)) {
roomLimits.set(roomId, userLimit);
}
// Check limit
const currentLimit = roomLimits.get(roomId) || 10; // Default 10
const users = roomUsers.get(roomId);
const currentUniqueUsers = users ? users.size : 0;
// If user is NEW to the room (not just a refresh) and room is full
const isNewUser = !users || !users.has(userId);
if (isNewUser && currentUniqueUsers >= currentLimit) {
socket.emit("error", "Room is full");
return;
}
socket.join(roomId);
if (nickname) {
socketNicknames.set(socket.id, nickname);
}
console.log(`Socket ${socket.id} (User ${userId}) joined room ${roomId}`);
// Initialize room tracking if needed
if (!roomUsers.has(roomId)) {
roomUsers.set(roomId, new Map());
}
const roomUserMap = roomUsers.get(roomId);
// Increment socket count for this user
const currentCount = roomUserMap.get(userId) || 0;
roomUserMap.set(userId, currentCount + 1);
// ALWAYS notify others about the new socket for Key Exchange
// Include nickname in the event
socket.to(roomId).emit("user-joined", { socketId: socket.id, userId, nickname });
// Broadcast new unique user count to EVERYONE (including sender)
io.to(roomId).emit("room-info", { count: roomUserMap.size, limit: currentLimit });
});
socket.on("send-message", (data) => {
// data: { roomId, encryptedMessage, senderId, messageId }
// Broadcast to others in the room
socket.to(data.roomId).emit("receive-message", data);
});
socket.on("message-delivered", (data) => {
// data: { roomId, messageId, senderId, recipientId }
io.to(data.roomId).emit("message-status", {
messageId: data.messageId,
status: "delivered",
recipientId: data.recipientId,
originalSenderId: data.senderId
});
});
socket.on("message-read", (data) => {
io.to(data.roomId).emit("message-status", {
messageId: data.messageId,
status: "read",
recipientId: data.recipientId,
originalSenderId: data.senderId
});
});
socket.on("signal", (data) => {
// WebRTC/Key Exchange signaling
// data: { target, signal, sender }
io.to(data.target).emit("signal", {
sender: socket.id,
signal: data.signal,
});
});
socket.on("disconnecting", () => {
for (const roomId of socket.rooms) {
if (roomId !== socket.id) {
const users = roomUsers.get(roomId);
if (users) {
const currentCount = users.get(userId) || 0;
if (currentCount > 1) {
users.set(userId, currentCount - 1);
} else {
users.delete(userId);
if (users.size === 0) {
roomUsers.delete(roomId);
roomLimits.delete(roomId);
}
}
// Always notify about socket leaving for Key Cleanup
socket.to(roomId).emit("user-left", { socketId: socket.id, userId });
socketNicknames.delete(socket.id);
// Broadcast new count
io.to(roomId).emit("room-info", { count: users.size });
}
}
}
});
socket.on("disconnect", () => {
console.log("Client disconnected:", socket.id);
});
});
httpServer.listen(3001, () => {
console.log("Test server ready on http://localhost:3001");
});
|