javascript - Socket IO 发出事件两次

标签 javascript node.js reactjs express socket.io

情况:

我正在使用 socket.io 设置一个 Express 服务器,并使用 ReactJS 设置一个客户端。这是我的服务器:

//... another requirement
const socket = require("./socket");

const app = express();
const server = http.createServer(app);
const port = process.env.PORT || 3000;

//... some parsers ...

routes(app);
socket(server);

server.listen(port);
console.log("Server started on: " + port);

这是我的套接字:

const socketIO = require("socket.io");

const socket = server => {
  const io = socketIO(server);
  const chat = io.of("/chat");
  chat.on("connection", client => {
    console.log("User started chat!");
    client.on("disconnect", () => {
      console.log("User left chat!");
    });

    client.on("sendMessage", msg => {
      const { id, text } = msg;
      console.log(id + " says: " + text);
      client.broadcast.emit("incomingMessage", {
        //... response data
      });
    });
  });
};

在客户端,聊天页面组件将处理向套接字发送消息以及从套接字接收消息:

//_ChatBox in Chat Page
const _ChatBox = (/*props*/) => {
  const chat = io("http://localhost" + ":3000/chat");

  chat.on("incomingMessage", message => {
    console.log("Receive message");
    //...handle income message
  });

  const sendMessageToSocket = (data) => {
    chat.emit("sendMessage", data);
  };

  return ( /*JSX*/);
};

问题:

每次用户访问聊天页面时,socket 都会收到 connect 事件并将 User started chat! 记录到控制台一次,但实际上,它已经记录了两次,这意味着 socket 已经处理了两次 connect 事件。

当 _ChatBox 收到消息时,它会记录接收消息并显示该消息,但它所做的是记录两次并显示该消息两次,这也意味着套接字已发出 IncomeMessage事件两次。

我想要的:我希望套接字只处理这些事件一次。

最佳答案

看起来您的组件渲染了两次,因此调用 const chat = io("http://localhost"+ ":3000/chat"); 两次,给出两条连接消息。

您可以使用 useEffect() Hook 仅在第一次渲染时连接。传入一个空数组作为第二个参数意味着该效果只会被调用一次:

const _ChatBox = (/*props*/) => {

  useEffect(()=>{
     const chat = io("http://localhost" + ":3000/chat");

    chat.on("incomingMessage", message => {
      console.log("Receive message");
      //...handle income message
     });

     const sendMessageToSocket = (data) => {
      chat.emit("sendMessage", data);
     };
   }, []);


  return ( /*JSX*/);
};

关于javascript - Socket IO 发出事件两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56278700/

相关文章:

css - 使用 SX 属性创建动画 - MUI v5

javascript - 如何定义 Node.js 应用上下文路径?

node.js - 如何从 multer 访问上传的文件?

javascript - jQueryUI 日期选择器突出显示第二天

JavaScript 执行

node.js - 这个 ejs 在 jade 中会是什么样子?

javascript - 使用列表从库中获取 react 组件

javascript - 在 ReactJS 中更改 URL onClick

javascript - HTML5 localStorage.setItem 不适用于 iOS 8 - Safari 移动版

java - 是否可以在 Vaadin 框架内使用 jQuery?