UNPKG

networked-aframe

Version:

A web framework for building multi-user virtual reality experiences.

142 lines (117 loc) 4.29 kB
const express = require("express"); const path = require("node:path"); const http = require("node:http"); // To generate a certificate for local development with https, you can use // npx webpack serve --server-type https // and stop it with ctrl+c, it will generate the file node_modules/.cache/webpack-dev-server/server.pem // Then to enable https on the node server, uncomment the next lines // and the webServer line down below. // const https = require("node:https"); // const fs = require("node:fs"); // const privateKey = fs.readFileSync("node_modules/.cache/webpack-dev-server/server.pem", "utf8"); // const certificate = fs.readFileSync("node_modules/.cache/webpack-dev-server/server.pem", "utf8"); // const credentials = { key: privateKey, cert: certificate }; // Set process name process.title = "networked-aframe-server"; // Get port or default to 8080 const port = process.env.PORT || 8080; // Threshold for instancing a room const maxOccupantsInRoom = 50; // Setup and configure Express http server. const app = express(); // Serve the bundle in-memory in development (needs to be before the express.static) if (process.env.NODE_ENV === "development") { const webpackMiddleware = require("webpack-dev-middleware"); const webpack = require("webpack"); const config = require("../webpack.config"); app.use( webpackMiddleware(webpack(config), { publicPath: "/dist/" }) ); } // Serve the files from the examples folder app.use(express.static(path.resolve(__dirname, "..", "examples"))); // Start Express http server const webServer = http.createServer(app); // To enable https on the node server, comment the line above and uncomment the line below // const webServer = https.createServer(credentials, app); const io = require("socket.io")(webServer); const rooms = new Map(); io.on("connection", (socket) => { console.log("user connected", socket.id); let curRoom = null; socket.on("joinRoom", (data) => { const { room } = data; curRoom = room; let roomInfo = rooms.get(room); if (!roomInfo) { roomInfo = { name: room, occupants: {}, occupantsCount: 0 }; rooms.set(room, roomInfo); } if (roomInfo.occupantsCount >= maxOccupantsInRoom) { // If room is full, search for spot in other instances let availableRoomFound = false; const roomPrefix = `${room}--`; let numberOfInstances = 1; for (const [roomName, roomData] of rooms.entries()) { if (roomName.startsWith(roomPrefix)) { numberOfInstances++; if (roomData.occupantsCount < maxOccupantsInRoom) { availableRoomFound = true; curRoom = roomName; roomInfo = roomData; break; } } } if (!availableRoomFound) { // No available room found, create a new one const newRoomNumber = numberOfInstances + 1; curRoom = `${roomPrefix}${newRoomNumber}`; roomInfo = { name: curRoom, occupants: {}, occupantsCount: 0 }; rooms.set(curRoom, roomInfo); } } const joinedTime = Date.now(); roomInfo.occupants[socket.id] = joinedTime; roomInfo.occupantsCount++; console.log(`${socket.id} joined room ${curRoom}`); socket.join(curRoom); socket.emit("connectSuccess", { joinedTime }); const occupants = roomInfo.occupants; io.in(curRoom).emit("occupantsChanged", { occupants }); }); socket.on("send", (data) => { io.to(data.to).emit("send", data); }); socket.on("broadcast", (data) => { socket.to(curRoom).emit("broadcast", data); }); socket.on("disconnect", () => { console.log("disconnected: ", socket.id, curRoom); const roomInfo = rooms.get(curRoom); if (roomInfo) { console.log("user disconnected", socket.id); delete roomInfo.occupants[socket.id]; roomInfo.occupantsCount--; const occupants = roomInfo.occupants; socket.to(curRoom).emit("occupantsChanged", { occupants }); if (roomInfo.occupantsCount === 0) { console.log("everybody left room"); rooms.delete(curRoom); } } }); }); webServer.listen(port, () => { console.log("listening on http://localhost:" + port); });