Qonfucius / excalidraw-room

https://portal.excalidraw.com
MIT License
0 stars 0 forks source link

Add a redis backend to socket.io #1

Open Nainterceptor opened 1 year ago

Nainterceptor commented 1 year ago
Nainterceptor commented 1 year ago

https://github.com/excalidraw/excalidraw/blob/master/package.json#L54 is using fixed version for socket io client, so we have to use old version I guess.

Suggest to fix current version and add carets ```diff diff --git a/package.json b/package.json index b7fc91a..6704830 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,24 @@ { "dependencies": { - "@excalidraw/eslint-config": "1.0.1", - "@excalidraw/prettier-config": "1.0.2", - "@types/debug": "4.1.5", - "@types/express": "4.17.11", - "@types/node": "14.14.31", - "@types/socket.io": "2.1.4", - "@typescript-eslint/eslint-plugin": "4.16.1", - "@typescript-eslint/parser": "4.16.1", + "@excalidraw/eslint-config": "^1.0.1", + "@excalidraw/prettier-config": "^1.0.2", + "@types/debug": "^4.1.5", + "@types/express": "^4.17.11", + "@types/node": "^14.14.31", + "@types/socket.io": "^2.1.4", + "@typescript-eslint/eslint-plugin": "^4.16.1", + "@typescript-eslint/parser": "^4.16.1", "cross-env": "^7.0.3", - "debug": "4.3.1", + "debug": "^4.3.1", "dotenv": "^10.0.0", - "eslint": "7.21.0", - "eslint-config-prettier": "8.1.0", - "eslint-plugin-prettier": "3.3.1", - "express": "4.17.1", - "prettier": "2.2.1", - "socket.io": "2.3.0", + "eslint": "^7.21.0", + "eslint-config-prettier": "^8.1.0", + "eslint-plugin-prettier": "^3.3.1", + "express": "^4.17.1", + "prettier": "^2.2.1", + "socket.io": "^2.3.0", "ts-node-dev": "^1.1.8", - "typescript": "4.2.3" + "typescript": "^4.2.3" }, "license": "MIT", "main": "dist/index.js", diff --git a/src/index.ts b/src/index.ts index 6c9da5e..c8e956e 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import debug from "debug"; import express from "express"; -import http from "http"; +import http, { OutgoingHttpHeaders } from "http"; import socketIO from "socket.io"; const serverDebug = debug("server"); @@ -30,11 +30,11 @@ server.listen(port, () => { const io = socketIO(server, { handlePreflightRequest: (req, res) => { - const headers = { + const headers: OutgoingHttpHeaders = { "Access-Control-Allow-Headers": "Content-Type, Authorization", "Access-Control-Allow-Origin": - (req.header && req.header.origin) || "https://excalidraw.com", - "Access-Control-Allow-Credentials": true, + (req.headers && req.headers.origin) || "https://excalidraw.com", + "Access-Control-Allow-Credentials": "true", }; res.writeHead(200, headers); res.end(); ```
Suggest to update socket io server and add redis support ```diff diff --git a/package.json b/package.json index b7fc91a..47d44de 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,26 @@ { "dependencies": { - "@excalidraw/eslint-config": "1.0.1", - "@excalidraw/prettier-config": "1.0.2", - "@types/debug": "4.1.5", - "@types/express": "4.17.11", - "@types/node": "14.14.31", - "@types/socket.io": "2.1.4", - "@typescript-eslint/eslint-plugin": "4.16.1", - "@typescript-eslint/parser": "4.16.1", + "@excalidraw/eslint-config": "^1.0.1", + "@excalidraw/prettier-config": "^1.0.2", + "@socket.io/redis-adapter": "^8.1.0", + "@types/debug": "^4.1.5", + "@types/express": "^4.17.11", + "@types/node": "^14.14.31", + "@types/socket.io": "^2.1.4", + "@typescript-eslint/eslint-plugin": "^4.16.1", + "@typescript-eslint/parser": "^4.16.1", "cross-env": "^7.0.3", - "debug": "4.3.1", + "debug": "^4.3.1", "dotenv": "^10.0.0", - "eslint": "7.21.0", - "eslint-config-prettier": "8.1.0", - "eslint-plugin-prettier": "3.3.1", - "express": "4.17.1", - "prettier": "2.2.1", - "socket.io": "2.3.0", + "eslint": "^7.21.0", + "eslint-config-prettier": "^8.1.0", + "eslint-plugin-prettier": "^3.3.1", + "express": "^4.17.1", + "prettier": "^2.2.1", + "redis": "^4.6.6", + "socket.io": "^4.6.1", "ts-node-dev": "^1.1.8", - "typescript": "4.2.3" + "typescript": "^4.2.3" }, "license": "MIT", "main": "dist/index.js", diff --git a/src/index.ts b/src/index.ts index 6c9da5e..fb6d0b8 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,9 @@ import debug from "debug"; import express from "express"; import http from "http"; -import socketIO from "socket.io"; +import { Server } from "socket.io"; +import { createAdapter } from "@socket.io/redis-adapter"; +import Redis from "redis"; const serverDebug = debug("server"); const ioDebug = debug("io"); @@ -24,20 +26,28 @@ app.get("/", (req, res) => { const server = http.createServer(app); -server.listen(port, () => { - serverDebug(`listening on port: ${port}`); -}); +let adapterOptions = {}; -const io = socketIO(server, { - handlePreflightRequest: (req, res) => { - const headers = { - "Access-Control-Allow-Headers": "Content-Type, Authorization", - "Access-Control-Allow-Origin": - (req.header && req.header.origin) || "https://excalidraw.com", - "Access-Control-Allow-Credentials": true, - }; - res.writeHead(200, headers); - res.end(); +if (process.env.REDIS_URL) { + const pubClient = Redis.createClient({ url: process.env.REDIS_URL }); + const subClient = pubClient.duplicate(); + + adapterOptions = { + adapter: createAdapter(pubClient, subClient), + }; +} + +const io = new Server(server, { + ...adapterOptions, + cors: { + origin: (origin, callback) => { + if (!origin || origin === "https://excalidraw.com") { + callback(null, true); + } else { + callback(new Error("Not allowed by CORS")); + } + }, + credentials: true, }, }); @@ -47,15 +57,13 @@ io.on("connection", (socket) => { socket.on("join-room", (roomID) => { socketDebug(`${socket.id} has joined ${roomID}`); socket.join(roomID); - if (io.sockets.adapter.rooms[roomID].length <= 1) { + const sessions = Array.from(io.sockets.adapter.rooms.get(roomID) ?? []); + if (sessions.length <= 1) { io.to(`${socket.id}`).emit("first-in-room"); } else { socket.broadcast.to(roomID).emit("new-user", socket.id); } - io.in(roomID).emit( - "room-user-change", - Object.keys(io.sockets.adapter.rooms[roomID].sockets), - ); + io.in(roomID).emit("room-user-change", Object.keys(sessions)); }); socket.on( @@ -79,7 +87,7 @@ io.on("connection", (socket) => { socket.on("disconnecting", () => { const rooms = io.sockets.adapter.rooms; for (const roomID in socket.rooms) { - const clients = Object.keys(rooms[roomID].sockets).filter( + const clients = Array.from(rooms.get(roomID) ?? []).filter( (id) => id !== socket.id, ); if (clients.length > 0) { @@ -92,3 +100,7 @@ io.on("connection", (socket) => { socket.removeAllListeners(); }); }); + +server.listen(port, () => { + serverDebug(`listening on port: ${port}`); +}); ```

Upgrade is not working cause of outdated socket io client on excalidraw main repo. Both solutions are not working locally, cause of unmaintained repo ? (Twitter)