为什么我的套接字进入无限循环



前端:

useEffect(() => {
socketRef.current = io.connect("...", { transports : ['websocket'] })
socketRef.current.emit("online", id)
socketRef.current.on("message", ({ name, message }) => {
setChat([ ...chat, { name, message , system: false } ])
})
socketRef.current.on("online", ( userID ) => {
setChat([ ...chat, { name: userID , message: `has logged on` , system: true } ])
})
socketRef.current.on("offline", ( userID ) => {
setChat([ ...chat, { name: userID , message: `${userID} has logged off` , system: true } ])
})
return () => {
socketRef.current.disconnect()
}
},[ chat ])

后端:

io.on('connection', socket => {
socket.on('message', ({ name, message , userID }) => {
io.emit('message', { name, message , userID })
})
socket.on('online', ( userID ) => {
onlineApprovers.push({ user: userID , id: socket.id })
console.log(userID + ' is online')
io.emit('online', userID)
})
socket.on('disconnect', () => {
console.log(onlineApprovers.find(a => a.id === socket.id).user + ' is offline')
io.emit('offline', onlineApprovers.find(a => a.id === socket.id).user)
})
})

我的代码所做的一点上下文:当用户进入我的网站时,它会获取他们的用户id,发出online套接字事件,然后后端记录userid is online,当他们离开我的网站后,套接字将断开连接,然后记录userid is offline

有人能告诉我为什么这会进入一个无限循环吗?当我登录时,它会一直记录123 is online,然后记录123 is offline,然后再记录123 is online,以此类推。当我甚至没有关闭窗口时,它就会记录下来。

/编辑/

从我的代码中删除这些之后:

// socketRef.current.on("online", ( userID ) => {
//  setChat([ ...chat, { name: userID , message: `has logged on` , system: true } ])
// })
// socketRef.current.on("offline", ( userID ) => {
//  setChat([ ...chat, { name: userID , message: `${userID} has logged off` , system: true } ])
// })       

它不会以无限循环结束,但我的前端无法从后端接收数据。

当用户加入/chat状态更改时,将向服务器发出online事件,然后服务器通过向所有连接的客户端发出online事件来响应,这将导致以下侦听器执行:

socketRef.current.on("online", ( userID ) => {
setChat([ ...chat, { name: userID , message: `has logged on` , system: true } ])
})

当您在这里调用setChat()并通过一个新数组时,这会导致react组件重新渲染,从而再次执行use-effect函数。然后再次触发online事件,从而导致循环。

相反,您可以在组件装载时通过将[]作为对useEffect()的依赖项传递来创建套接字连接,并使用setChat()的状态更新器函数来访问chat:的最新值

useEffect(() => {
socketRef.current = io.connect("...", { transports : ['websocket'] });
socketRef.current.emit("online", id);
socketRef.current.on("message", ({ name, message }) => {
setChat(chat => [ ...chat, { name, message , system: false } ]);
});
socketRef.current.on("online", ( userID ) => {
setChat(chat => [ ...chat, { name: userID , message: `has logged on` , system: true } ]);
});
socketRef.current.on("offline", ( userID ) => {
setChat(chat => [ ...chat, { name: userID , message: `${userID} has logged off` , system: true } ]);
});
return () => {
socketRef.current.disconnect();
};
}, []);

最新更新