From e8ee5811a031b4b34711e10781abfc15ad21730b Mon Sep 17 00:00:00 2001 From: Thibaut Valentin Date: Fri, 2 Jan 2026 23:12:22 +0100 Subject: [PATCH] feat: avoid ws reconnect when user logged out --- src/main/webapp/src/hooks/useWS.jsx | 68 ++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/main/webapp/src/hooks/useWS.jsx b/src/main/webapp/src/hooks/useWS.jsx index bd05b73..ef5f0c0 100644 --- a/src/main/webapp/src/hooks/useWS.jsx +++ b/src/main/webapp/src/hooks/useWS.jsx @@ -1,6 +1,4 @@ import {createContext, useContext, useEffect, useId, useReducer, useRef, useState} from "react"; -import {apiAxios} from "../utils/Tools.js"; -import {toast} from "react-toastify"; import {useAuth} from "./useAuth.jsx"; function uuidv4() { @@ -45,6 +43,7 @@ export function WSProvider({url, onmessage, children}) { const id = useId(); const {is_authenticated} = useAuth() const [isReady, setIsReady] = useState(false) + const [doReconnect, setDoReconnect] = useState(false) const [state, dispatch] = useReducer(reducer, {listener: []}) const ws = useRef(null) const listenersRef = useRef([]) @@ -59,10 +58,33 @@ export function WSProvider({url, onmessage, children}) { listenersRef.current = state.listener }, [state.listener]) + useEffect(() => { + if (!doReconnect && !is_authenticated && isReady) + return; + + const timer = setInterval(() => { + if (isReady || !doReconnect || !is_authenticated) + return; + + console.log("WSProvider: reconnecting to", url); + try { + const newSocket = new WebSocket(url) + newSocket.onopen = ws.current.onopen + newSocket.onclose = ws.current.onclose + newSocket.onmessage = ws.current.onmessage + ws.current = newSocket + }catch (e) { + + } + }, 5000); + return () => clearInterval(timer); + }, [isReady, doReconnect, is_authenticated]); + useEffect(() => { if (!mountCounter[id]) mountCounter[id] = 0 mountCounter[id] += 1 + setDoReconnect(true) console.log(`WSProvider ${id} mounted ${mountCounter[id]} time(s)`); if (mountCounter[id] === 1 && (ws.current === null || ws.current.readyState >= WebSocket.CLOSING)){ @@ -72,24 +94,6 @@ export function WSProvider({url, onmessage, children}) { socket.onopen = () => setIsReady(true) socket.onclose = () => { setIsReady(false) - if (mountCounter[id] > 0) { - setTimeout(() => { - //if (is_authenticated){ - console.log("WSProvider: reconnecting to", url); - try { - const newSocket = new WebSocket(url) - ws.current = newSocket - newSocket.onopen = socket.onopen - newSocket.onclose = socket.onclose - newSocket.onmessage = socket.onmessage - }catch (e) { - - } - //}else{ - // console.log("WSProvider: not reconnecting, user is not authenticated"); - //} - }, 5000) - } } socket.onmessage = (event) => { const msg = JSON.parse(event.data) @@ -132,6 +136,7 @@ export function WSProvider({url, onmessage, children}) { setTimeout(() => { console.log(`WSProvider ${id} checking for close, ${mountCounter[id]} instance(s) remain`); if (mountCounter[id] === 0) { + setDoReconnect(false) console.log("WSProvider: closing connection to", url); ws.current.close() } @@ -139,13 +144,14 @@ export function WSProvider({url, onmessage, children}) { } }, []) - const send = (uuid, code, type, data, resolve = () => { + const send2 = (uuid, code, type, data, resolve = () => { }, reject = () => { }) => { if (!isReadyRef.current) { reject("WebSocket is not connected"); return; } + if (type === "REQUEST") { const timeout = setTimeout(() => { reject("timeout"); @@ -172,6 +178,26 @@ export function WSProvider({url, onmessage, children}) { data: data })) } + const send = (uuid, code, type, data, resolve = () => { + }, reject = () => { + }) => { + if (isReadyRef.current) { + send2(uuid, code, type, data, resolve, reject); + }else { + let counter = 0; + const waitInterval = setInterval(() => { + if (isReadyRef.current) { + clearInterval(waitInterval); + send2(uuid, code, type, data, resolve, reject); + } + counter += 1; + if (counter >= 300) { // 30 seconds timeout + clearInterval(waitInterval); + reject("WebSocket is not connected"); + } + }, 100); + } + } const ret = {isReady, dispatch, send, wait_length: callbackRef}