簡體   English   中英

負載平衡與 socket.io 服務器與 nginx 使用 redis

[英]Load balancing with socket.io server with nginx using redis

我正在使用TypescriptNode.jsSocket.ioReact前端進行聊天項目。 我的應用程序在單個服務器實例上運行良好。 但是,當與多個服務器進行負載平衡時,聊天功能不起作用。 我使用 Redis 和 @socket.io/redis-adapter 來解決這個問題。 但它仍然無法正常工作。 我在哪里做錯了?

這是我的 nginx conf

upstream backend {
      server 127.0.0.1:8000; 
      server 127.0.0.1:8001;
   }

   server {
      listen 80; 

      location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $host;
          proxy_pass http://backend;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
      }
    }

這是我在 server.js 中的 socket.io 實現

const server = http.createServer(app);

const io = new Server<ClientToServerEvents, ServerToClientEvents>(server, {
  cors: {
    origin: process.env.NODE_ENV === "production" ? process.env.ALLOWED_HOST: "http://localhost:3000",
    methods: ["GET", "POST"],
    credentials: true
  },
  transports: ['websocket']
});

// redis config


const pubClient = createClient({ url: 'redis://localhost:6379'});
const subClient = pubClient.duplicate();

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  io.adapter(createAdapter(pubClient, subClient));
});


// routes
app.get("/", (req, res) => {
  res.send("Welcome to Node.js Server. 🚀 Server running on port 8000.");
});

app.use("/api/v1", apiRoutes);

// ********** Socket Start *********** //

// array of objects that stores online users
let users: { socketId: string; userId: string; username: string }[] = [];

// method for adding new user into users array
const addUser = (userId: string, socketId: string, username: string) => {
  if (
      userId &&
      !users.some((user) => user.socketId === socketId && user.userId === userId)
  ) {
    if (users.some((user) => user.socketId === socketId)) {
      users = users.filter((user) => user.socketId !== socketId);
    }
    users.push({ userId, socketId, username });
  }
};

// method for removing disconnected user from users array
const removeUser = (socketId: string) => {
  users = users.filter((user) => user.socketId !== socketId);
};

// method for getting user from users array
const getReceiver = (
    receiverId: string,
    senderId: string,
    socketId: string
) => {
  return users.filter(
      (user) =>
          user.userId === receiverId ||
          (user.userId === senderId && user.socketId !== socketId)
  );
};

// starting socket connection
io.on("connection", (socket) => {
  // establishing connection with client
  console.log(`a client connected on websocket.SocketId:${socket.id}`);

 //taking userId and username from client and pushing to users array along with socket id
  socket.on("addUser", ({ userId, username }) => {
    addUser(userId, socket.id, username);
    io.emit(SocketEvents.GET_USERS, users);  // sending online users to client side
  });

  //receiving message from sender and sending to the receiver
  socket.on("sendMessage", (message, receiverId) => {
    const user = getReceiver(receiverId, message.senderId, socket.id);
    if (user.length > 0) {
      user.forEach((u) => {
        io.to(u.socketId).emit("receiveMessage", message);
        socket.broadcast.emit('test' , {username: 'test'});
      });
    } else {
      io.to(socket.id).emit("error", "message not sent. receiver is offline");
    }
  });


  // disconnection of a client
  socket.on("disconnect", () => {
    console.log(`a client disconnected from websocket.SocketId:${socket.id}`);
    removeUser(socket.id);
  });
});

// 404 not found handler
app.use(notFoundHandler);

// common error handler
app.use(errorHandler);

// ********** Socket End *********** //

server.listen(port,
    () => console.log(`🚀 Server running on port ${port}`));

Socket.io 需要粘性會話,不確定 nginx 的免費版本是否支持它。
另一種選擇是從 Socket.io 文檔中禁用 HTTP 長輪詢傳輸:

如果您禁用 HTTP 長輪詢傳輸(這是 2021 年完全有效的選擇),您將不需要粘性會話:

您可以像這樣禁用它:

io("https://example.com", {
  transports: ["websocket"]
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM