发送 15 条消息后,带套接字的 React 聊天应用程序速度变慢
React chat application with socket slows down after 15 messages are sent
我是一名新开发人员,正在尝试制作一个相当强大的 React 项目,在此 project/website 中有一个页面包含一些自定义选项卡,其中一个选项卡是聊天。此聊天使用套接字与服务器通信。问题是发送大约 15-20 条消息后,任何接收聊天消息的客户端都会冻结很长一段时间。这是我如何在我的反应客户端中实现套接字。
我有一个名为 socket.js:
的实用程序文件
import io from "socket.io-client";
const SOCKET_URL = "http://localhost:3001";
export const socket = io(SOCKET_URL, { transports : ['websocket'] });
在使用套接字的反应组件中:
import {socket} from "../../utils/socket";
// This code runs (I think) only when the chat state variable changes or when I receive a socket update from the server
useEffect(()=>{
socket.on("chat msg sent",(chatObj)=>{
setChat([...chat,chatObj])
})
},[socket,chat])
// This code is being run when someone sends a chat
const sendChat = (msg) => {
const socketObj = {name:props.userState.username, content:msg, id,}
console.log(socketObj);
socket.emit("sending chat msg",socketObj)
const clientObj = {name:props.userState.username, content:msg}
setChat([...chat,clientObj]);
}
这是此 React 组件返回的内容:
return (
<div className="container-fluid p-0 m-0 border border-3 border-danger">
<div className="row p-0 m-0">
<div className="col-3 border border-primary border-4"><h1></h1></div>
<div className="col-7 border border-info border-4"></div>
<div className="col-2 border border-success border-4">
<div className="tab">
<button className="tablinks" onClick={()=>setTab('chat')}>Chat</button>
<button className="tablinks" onClick={()=>setTab('characters')}>Char</button>
<button className="tablinks" onClick={()=>setTab('compendium')}>Comp</button>
<button className="tablinks" onClick={()=>setTab('settings')}>Sett</button>
</div>
<div className="tab-content">
{tabContent}
</div>
</div>
</div>
<Character/>
</div>
);
选择聊天选项卡时,tabContent 状态变量设置为:
setTabContent(
<div>
<ul className="chat">
{chat.map((entry)=>{
return(
<li>
<h6>{entry.name}</h6>
<p>{entry.content}</p>
</li>
)
})}
</ul>
<form onSubmit={(e)=>{
e.preventDefault();
sendChat(chatInput);
setChatInput('');
}}>
<input className="" value={chatInput} onChange={(e)=>setChatInput(e.target.value)}/>
</form>
</div>
)
在后端我有一个名为 socketServer.js 的文件,这个文件包含任何套接字连接,它只是一个导出到主服务器文件的函数。
socketServer.js:
exports = module.exports = function (io) {
io.on('connection', function (socket) {
io.emit('greeting', 'welcome to our site!');
socket.on('join campaign room',(id)=>{
socket.join(id);
console.log("joining the campaign room", id);
});
socket.on('sending chat msg', (socketObj)=>{
console.log("cool beans", socketObj);
const chatObj = {name:socketObj.name, content:socketObj.content}
socket.broadcast.to(socketObj.id).emit('chat msg sent',chatObj);
});
});
}
总的来说,这一直有效,直到发送了太多消息,然后对于任何接收消息的人来说都变得非常慢。我不认为这是后端的问题,我认为这与套接字更新的反应状态变量有关,但我可能是错的。
每当您获得 setChat()
设置的新 chat
变量时,您的 useEffect 就会建立与 socket.io 的新连接。因此,在 15 条消息之后,您已经为套接字事件设置了 15 个侦听器 sending chat msg
。同时,在 useEffect 的清理过程中,您不会删除以前的侦听器。
你可以试试这个,只设置一个监听套接字事件
import {socket} from "../../utils/socket";
// This code runs (I think) only when the chat state variable changes or when I receive a socket update from the server
useEffect(()=>{
const setChat = (chatObj) => {
setChat(oldChat => [...oldChat, chatObj])
}
socket.on("chat msg sent", setChat)
return () => soket.removeListener("chat msg sent", setChat)
},[socket])
我是一名新开发人员,正在尝试制作一个相当强大的 React 项目,在此 project/website 中有一个页面包含一些自定义选项卡,其中一个选项卡是聊天。此聊天使用套接字与服务器通信。问题是发送大约 15-20 条消息后,任何接收聊天消息的客户端都会冻结很长一段时间。这是我如何在我的反应客户端中实现套接字。
我有一个名为 socket.js:
的实用程序文件import io from "socket.io-client";
const SOCKET_URL = "http://localhost:3001";
export const socket = io(SOCKET_URL, { transports : ['websocket'] });
在使用套接字的反应组件中:
import {socket} from "../../utils/socket";
// This code runs (I think) only when the chat state variable changes or when I receive a socket update from the server
useEffect(()=>{
socket.on("chat msg sent",(chatObj)=>{
setChat([...chat,chatObj])
})
},[socket,chat])
// This code is being run when someone sends a chat
const sendChat = (msg) => {
const socketObj = {name:props.userState.username, content:msg, id,}
console.log(socketObj);
socket.emit("sending chat msg",socketObj)
const clientObj = {name:props.userState.username, content:msg}
setChat([...chat,clientObj]);
}
这是此 React 组件返回的内容:
return (
<div className="container-fluid p-0 m-0 border border-3 border-danger">
<div className="row p-0 m-0">
<div className="col-3 border border-primary border-4"><h1></h1></div>
<div className="col-7 border border-info border-4"></div>
<div className="col-2 border border-success border-4">
<div className="tab">
<button className="tablinks" onClick={()=>setTab('chat')}>Chat</button>
<button className="tablinks" onClick={()=>setTab('characters')}>Char</button>
<button className="tablinks" onClick={()=>setTab('compendium')}>Comp</button>
<button className="tablinks" onClick={()=>setTab('settings')}>Sett</button>
</div>
<div className="tab-content">
{tabContent}
</div>
</div>
</div>
<Character/>
</div>
);
选择聊天选项卡时,tabContent 状态变量设置为:
setTabContent(
<div>
<ul className="chat">
{chat.map((entry)=>{
return(
<li>
<h6>{entry.name}</h6>
<p>{entry.content}</p>
</li>
)
})}
</ul>
<form onSubmit={(e)=>{
e.preventDefault();
sendChat(chatInput);
setChatInput('');
}}>
<input className="" value={chatInput} onChange={(e)=>setChatInput(e.target.value)}/>
</form>
</div>
)
在后端我有一个名为 socketServer.js 的文件,这个文件包含任何套接字连接,它只是一个导出到主服务器文件的函数。 socketServer.js:
exports = module.exports = function (io) {
io.on('connection', function (socket) {
io.emit('greeting', 'welcome to our site!');
socket.on('join campaign room',(id)=>{
socket.join(id);
console.log("joining the campaign room", id);
});
socket.on('sending chat msg', (socketObj)=>{
console.log("cool beans", socketObj);
const chatObj = {name:socketObj.name, content:socketObj.content}
socket.broadcast.to(socketObj.id).emit('chat msg sent',chatObj);
});
});
}
总的来说,这一直有效,直到发送了太多消息,然后对于任何接收消息的人来说都变得非常慢。我不认为这是后端的问题,我认为这与套接字更新的反应状态变量有关,但我可能是错的。
每当您获得 setChat()
设置的新 chat
变量时,您的 useEffect 就会建立与 socket.io 的新连接。因此,在 15 条消息之后,您已经为套接字事件设置了 15 个侦听器 sending chat msg
。同时,在 useEffect 的清理过程中,您不会删除以前的侦听器。
你可以试试这个,只设置一个监听套接字事件
import {socket} from "../../utils/socket";
// This code runs (I think) only when the chat state variable changes or when I receive a socket update from the server
useEffect(()=>{
const setChat = (chatObj) => {
setChat(oldChat => [...oldChat, chatObj])
}
socket.on("chat msg sent", setChat)
return () => soket.removeListener("chat msg sent", setChat)
},[socket])