情况:
我正在使用socket.io和一个使用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*/);
};
问题:
每次用户访问“聊天页面”时,套接字将接收连接事件并登录User started chat!
一次以进行控制台,但是实际上,它已记录两次,这意味着套接字已处理了两次连接事件。
当_ChatBox收到消息时,它将记录Receive message
并显示该消息,但是它所做的是两次记录该日志并显示两次消息,这也意味着套接字已发出了IncomeMessage事件两次。 / p>
我想要的东西:我希望套接字只处理一次这些事件。
答案 0 :(得分:1)
您的组件好像呈现了两次,因此调用const chat = io("http://localhost" + ":3000/chat");
两次,给出两条连接消息。
您可以使用useEffect()
钩子仅在第一个渲染器上进行连接。将空数组作为第二个参数传递意味着效果将仅被调用一次:
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*/);
};
答案 1 :(得分:0)
**在index.js文件中创建套接字,并作为道具传递给根应用程序组件,例如:-**
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import socketIOClient from "socket.io-client"
var socket = socketIOClient('http://localhost:9000');
ReactDOM.render(
<React.StrictMode>
<App socket={socket} />
</React.StrictMode>,
document.getElementById('root')
);
现在使用此套接字发出如下事件:-
import React from "react"
import './App.css';
class App extends React.Component {
componentDidMount() {
this.props.socket.emit('test')
}
render() {
return (
<div>
hello
</div>
);
}
}
export default App;
答案 2 :(得分:0)
我遇到了类似的问题。我通过在我的功能组件中编写来解决它 打开套接字 onMount(和 onUpdate)但在卸载时关闭套接字的 useEffect。
useEffect(()=>{
const socket = io("http://localhost:3000")
socket.on(userId, (arg) => {
//stuff
});
return () => socket.emit('end'); //Close socket on UNMOUNT
})