【问题标题】:Socket.io sends back multiple responses only to the senderSocket.io 仅将多个响应发送回发送者
【发布时间】:2021-04-22 20:23:38
【问题描述】:

所以我想深入研究 Socket.io,我是它的初学者。我是一名 React 开发人员并决定使用 React 对其进行测试,这是我的客户端:

import { io } from "socket.io-client";
function App() {
  let [message, setMessage] = useState("");
  let [messages, setMessages] = useState([]);
  const socket = io("http://localhost:4000/", {
    withCredentials: true,
    cors: {
      origin: "http://localhost:4000",
    },
  });

  const sendMessage = (msg) => {
    socket.emit("messageToServer", msg);
  };
  socket.on("messageToClient", (msg) => {
    setMessages((prevMessage) => prevMessage.concat(msg));
  });

  return (
    <div className="App">
      {messages}

      <input
        id="input"
        autoComplete="off"
        onChange={(e) => setMessage(e.target.value)}
      />
      <button onClick={() => sendMessage(message)}>Send</button>
    </div>
  );
}

这是我的服务器端(节点,Express):

const app = require("express")();
const http = require("http").Server(app);
const io = require("socket.io")(http, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"],
    credentials: true,
  },
});

io.on("connection", (socket) => {
  let messages = [];
  socket.on("messageToServer", (msg) => {
    io.emit("messageToClient", msg);
    console.log(msg);
  });
});

http.listen(4000, () => {
  console.log("listening on *:3000");
});

所以基本上当我在输入上写一些东西并单击按钮时,在节点服务器上一切似乎都很好,并且消息只记录一次,但是当我打开发送消息的选项卡时,例如我输入了“首先message' 它将打印类似:'First messageFirst messageFirst messageFirst message' 等等...... 但显然,重复只发生在我发送它的选项卡中,因为当我打开一个新选项卡并对其进行测试时,在发件人选项卡上我得到了多个,就像我说的那样,但在新选项卡上,我只收到一个,就像它应该的那样。 提前谢谢!

【问题讨论】:

    标签: javascript node.js reactjs socket.io


    【解决方案1】:

    下面的 sn-p 代码会保持 App 组件被多次渲染,因此 messageToClient 的同一个事件处理程序将被多次注册并导致 React 中出现意外行为。

      socket.on("messageToClient", (msg) => {
        setMessages((prevMessage) => prevMessage.concat(msg));
      });
    

    您应该使用useEffect 包装事件上的套接字,以便我们可以确保没有重复。

      useEffect(()=>{
        socket.on("messageToClient", (msg) => {
          setMessages((prevMessage) => prevMessage.concat(msg));
        });
        
        // unbind the event handler when the component gets unmounted
        return () => {
          socket.off('messageToClient')
        }
      },[])
    

    【讨论】:

    • 哦,我明白了!感谢您花时间解释,它成功了!
    猜你喜欢
    • 2017-05-16
    • 2012-09-19
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 2016-06-12
    • 2016-11-28
    相关资源
    最近更新 更多