|
|
@@ -0,0 +1,76 @@
|
|
|
+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}'.`);
|
|
|
+});
|