为什么我的套接字会进入无限循环?
why does my socket goes into a infinite loop?
前端:
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
,依此类推。它记录了当我什至没有关闭我的 window.
/编辑/
从我的代码中删除这些后:
// 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 } ])
// })
它并没有进入无限循环,但是我的前端无法从我的后端接收数据。
当用户 joins/the chat
状态发生变化时,您将向服务器发出 online
事件,然后服务器通过发出 online
响应该事件事件发送到所有连接的客户端,这会导致执行以下侦听器:
socketRef.current.on("online", ( userID ) => {
setChat([ ...chat, { name: userID , message: `has logged on` , system: true } ])
})
当你在这里调用 setChat()
并传递一个新数组时,这会导致你的反应组件重新渲染,从而使使用效果函数再次执行。然后,这会再次触发 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();
};
}, []);
前端:
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
,依此类推。它记录了当我什至没有关闭我的 window.
/编辑/
从我的代码中删除这些后:
// 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 } ])
// })
它并没有进入无限循环,但是我的前端无法从我的后端接收数据。
当用户 joins/the chat
状态发生变化时,您将向服务器发出 online
事件,然后服务器通过发出 online
响应该事件事件发送到所有连接的客户端,这会导致执行以下侦听器:
socketRef.current.on("online", ( userID ) => {
setChat([ ...chat, { name: userID , message: `has logged on` , system: true } ])
})
当你在这里调用 setChat()
并传递一个新数组时,这会导致你的反应组件重新渲染,从而使使用效果函数再次执行。然后,这会再次触发 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();
};
}, []);