import { Server } from "socket.io"; import { Redis } from "ioredis"; import jwt from "jsonwebtoken"; const jwtSecret = process.env.JWT_SECRET; const port = process.env.PORT || 3000; const io = new Server(port, { cors: { origin: "*", credentials: true, }, }); const redis = new Redis({ port: 6379, host: "redis", username: "default", password: process.env.REDIS_PASSWORD, db: 0, }); io.engine.use((req, res, next) => { const isHandshake = req._query.sid === undefined; if (!isHandshake) { return next(); } const header = req.headers["authorization"]; if (!header) { return next(new Error("no token")); } if (!header.startsWith("Bearer ")) { return next(new Error("invalid token")); } const token = header.substring(7); jwt.verify(token, jwtSecret, (err, decoded) => { if (err) { return next(new Error("invalid token")); } req.decodedToken = decoded; next(); }); }); io.on("connection", (socket) => { console.log(`connected with transport ${socket.conn.transport.name} and socket ${socket.id}`); socket.conn.on("upgrade", (transport) => { console.log(`transport upgraded to ${transport.name}`); }); socket.on("disconnect", (reason) => { console.log(`disconnected ${socket.id} due to ${reason}`); }); if(socket.request.decodedToken){ let user_id = parseInt(socket.request.decodedToken.sub) socket.join(user_id); } }); redis.subscribe("actions", (err, count) => { if (err) console.error(err.message); console.log(`Subscribed to ${count} channels.`); }); redis.on("message", function (channel, data) { data = JSON.parse(data).data; io.to(data.user_id).emit(data.action, data); console.log(`send new message to user ${data.user_id} in the channel '${channel}'.`); });