server.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { Server } from "socket.io";
  2. import { Redis } from "ioredis";
  3. import jwt from "jsonwebtoken";
  4. const jwtSecret = process.env.JWT_SECRET;
  5. const port = process.env.PORT || 3000;
  6. const io = new Server(port, {
  7. cors: {
  8. origin: "*",
  9. credentials: true,
  10. },
  11. });
  12. const redis = new Redis({
  13. port: 6379,
  14. host: "redis",
  15. username: "default",
  16. password: process.env.REDIS_PASSWORD,
  17. db: 0,
  18. });
  19. io.engine.use((req, res, next) => {
  20. const isHandshake = req._query.sid === undefined;
  21. if (!isHandshake) {
  22. return next();
  23. }
  24. const header = req.headers["authorization"];
  25. if (!header) {
  26. return next(new Error("no token"));
  27. }
  28. if (!header.startsWith("Bearer ")) {
  29. return next(new Error("invalid token"));
  30. }
  31. const token = header.substring(7);
  32. jwt.verify(token, jwtSecret, (err, decoded) => {
  33. if (err) {
  34. return next(new Error("invalid token"));
  35. }
  36. req.decodedToken = decoded;
  37. next();
  38. });
  39. });
  40. io.on("connection", (socket) => {
  41. console.log(`connected with transport ${socket.conn.transport.name} and socket ${socket.id}`);
  42. socket.conn.on("upgrade", (transport) => {
  43. console.log(`transport upgraded to ${transport.name}`);
  44. });
  45. socket.on("disconnect", (reason) => {
  46. console.log(`disconnected ${socket.id} due to ${reason}`);
  47. });
  48. if(socket.request.decodedToken){
  49. let user_id = parseInt(socket.request.decodedToken.sub)
  50. socket.join(user_id);
  51. }
  52. });
  53. redis.subscribe("actions", (err, count) => {
  54. if (err) console.error(err.message);
  55. console.log(`Subscribed to ${count} channels.`);
  56. });
  57. redis.on("message", function (channel, data) {
  58. data = JSON.parse(data).data;
  59. io.to(data.user_id).emit(data.action, data);
  60. console.log(`send new message to user ${data.user_id} in the channel '${channel}'.`);
  61. });