我有一个使用Socket.IO的React应用程序,套接字实例位于React组件中。
我一直注意到,注销和登录到我的应用程序中的操作(应该卸载组件并关闭连接,然后重新安装和重新打开连接)会导致套接字泄漏/重复套接字连接的创建。我还设法使应用程序进入一种状态,在这种状态下,它会迅速释放导致饥饿的新连接,但无法复制。这是一次成功的制作。
以下是客户端代码:
const Socket = React.memo(() => {
const [isLoadingSocket, setIsLoadingSocket] = useState<boolean>(false)
const socketRef = useRef<SocketIO<ServerToClientEvents, ClientToServerEvents> | null>(null)
const socketNeedsRestart = isFocused ? !isLoadingSocket : false
async function initializeSocket() {
const token = await getToken()
setIsLoadingSocket(true)
if (socketRef.current) {
socketRef.current.disconnect()
}
socketRef.current = io(`${SOCKET_HOST}`, {
secure: true,
reconnectionDelay: 5000,
transports: ['websocket', 'polling'],
path: ENVIRONMENT !== Environment.local ? '/api/socket.io/' : '',
auth: {
token,
},
})
console.log(`socket initialized`)
}
useEffect(() => {
if (socketNeedsRestart) {
initializeSocket()
}
}, [socketNeedsRestart]) //eslint-disable-line
useEffect(() => {
if (socketRef.current) {
socketRef.current.on(SocketLifecycleEvent.Connect, () => {
console.log('socket connected')
setIsLoadingSocket(false)
})
socketRef.current.on(SocketMessage.UsersOnline, (message) => {
updateOnlineUsers(message.onlineUserIDs)
})
}
return () => {
if (socketRef.current) {
socketRef.current.off(SocketLifecycleEvent.Connect)
socketRef.current.off(SocketLifecycleEvent.ConnectionError)
socketRef.current.off(SocketLifecycleEvent.Disconnect)
}
}
}, [isLoadingSocket])
useEffect(() => {
socketRef.current?.disconnect()
}, [])
return <></>
})
export default Socket该组件在用户登录后访问的页面中使用一次。我可以提供服务器代码,但它只会在每次有人连接时通知所有用户。是什么导致了连接泄漏?我怎么才能重新制造快速火灾泄漏呢?
发布于 2022-10-21 06:52:23
您的上一个useEffect是否正在做您期望的事情?看起来这应该是卸载上的清理,但是您没有返回函数。
你试过这样的东西吗?
useEffect( () => () => socketRef.current?.disconnect(), [] );https://stackoverflow.com/questions/74148013
复制相似问题