前端:
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();
};
}, []);