Socket.io: 服务器端发出如果是某个值则不发送

Socket.io: Server side emit doesn't send if it's a certain value

我目前正在做一个个人项目,运行 在 socket.io

方面遇到了一些麻烦

我正在尝试从服务器发出一个套接字,但是,只有当套接字 value/address 从 /lobby/invalid 更改为 /lobby/info 时才会传送套接字。

哦,还有,我正在为这个项目使用 MERN 堆栈。

服务器

//# Loading a lobby
  socket.on(`/lobby/load`, async (req, res) => {
    let doesExist = (game.lobbies[req.id] !== undefined)
    // Return user if the lobby doesn't exist
    if(doesExist === false) {
      console.log(LogError(`Error: Lobby does not exist!`))
      console.log(socket.id)
      io.to(socket.id).emit(`/lobby/invalid`, {}) // This does NOT send unless I change the value to "/lobby/info"
      return
    } else { // if the lobby does exist cont.
        io.to(socket.id).emit(`/lobby/info`, { // THIS WORKS
          settings: game.lobbies[req.id].settings,
          players: game.lobbies[req.id].players,
          chat: game.lobbies[req.id].chat,
          game: game.lobbies[req.id].game,
        })
    }
  })

客户端

componentDidMount() {
    let id = window.location.pathname
    id = id.substr(7)
    
    //# Lobby info request
    socket.emit(`/lobby/load`, { id: id, uid: cookies.get("id") })
    //# Lobby invalid await
    socket.on(`/lobby/invalid`, (data) => {
      console.error(`ERROR: Lobby doesnt' exist, RETURN`)
    })
    //# Lobby info waiter
    socket.on(`/lobby/info`, (data) => {
      this.setState(data)
      console.log(this.state)
    })
  }

嘿,通常当我将 socket.io 与单用户发射一起使用时,我正在使用回调方法,如下所示。

// server side
socket.on(`/lobby/load`, (data, callback) => {
  let doesExist = (typeof game.lobbies[data.id] !== "undefined");
  let payload = {
    state: "invalid",
  };

  if(doesExist) {
    payload.state = "info";
    payload.settings = game.lobbies[data.id].settings;
    payload.players = game.lobbies[data.id].players;
    payload.chat = game.lobbies[data.id].chat;
    payload.game = game.lobbies[data.id].game;
  }

  // return the payload to user via callback
  callback(payload);

  process.nextTick(() => (payload = null));
  // null the payload reference so node's GC can clean up the memory :)
});

这里请注意,回调应该是最后发送的,不能在payload数据

里面发送回调函数

对于客户端:

socket.emit(`/lobby/load`, { id: id, uid: cookies.get("id") }, (payload) => {
  if (payload.state === "invalid") {
    return console.log("invalid game id!!");
  }

  this.setState(payload);
  console.log(this.state);
});

在使用这种方法的最后,您不需要删除组件取消月时监听的事件。 :)

这就是我使用它的主要原因,而且当您发送服务器端发出的消息时,用户始终可以打开控制台并收听您的数据:)(也可以防止这种情况发生,因为一切都通过回调进行=)

关于发送回调,它实际上在 socket.io 的文档中称为 ack,您可以在此处查看:https://socket.io/docs/v4/client-api/index.html#socket-emit-eventName-%E2%80%A6args-ack