Fix socket.io warning

This commit is contained in:
Mathias Wagner 2025-03-01 00:42:45 +01:00
parent a3daab2f84
commit 184aa09fcf
3 changed files with 104 additions and 37 deletions

View File

@ -8,13 +8,15 @@ export const SocketProvider = ({ children }) => {
const [connected, setConnected] = useState(false); const [connected, setConnected] = useState(false);
const connectAttempts = useRef(0); const connectAttempts = useRef(0);
const maxAttempts = 3; const maxAttempts = 3;
const reconnectDelay = 2000; // ms const pendingEventHandlers = useRef({});
const isConnecting = useRef(false);
// Connect to socket server
const connect = useCallback(() => { const connect = useCallback(() => {
if (socket) return; if (socket || isConnecting.current) return;
isConnecting.current = true;
console.log("Connecting to socket server...");
// Determine server URL based on environment
const serverUrl = process.env.NODE_ENV === 'production' const serverUrl = process.env.NODE_ENV === 'production'
? window.location.origin ? window.location.origin
: 'http://localhost:5287'; : 'http://localhost:5287';
@ -23,15 +25,23 @@ export const SocketProvider = ({ children }) => {
const newSocket = io(serverUrl, { const newSocket = io(serverUrl, {
reconnectionAttempts: 3, reconnectionAttempts: 3,
timeout: 10000, timeout: 10000,
reconnectionDelay: 1000 reconnectionDelay: 1000,
autoConnect: true
}); });
newSocket.on('connect', () => { newSocket.on('connect', () => {
console.log('Socket connected with ID:', newSocket.id); console.log('Socket connected with ID:', newSocket.id);
setConnected(true); setConnected(true);
connectAttempts.current = 0; connectAttempts.current = 0;
isConnecting.current = false;
Object.entries(pendingEventHandlers.current).forEach(([event, handlers]) => {
handlers.forEach(handler => {
console.log(`Registering pending handler for event: ${event}`);
newSocket.on(event, handler);
});
});
// Store player ID in localStorage for persistence
localStorage.setItem('playerId', newSocket.id); localStorage.setItem('playerId', newSocket.id);
}); });
@ -43,6 +53,7 @@ export const SocketProvider = ({ children }) => {
newSocket.on('connect_error', (error) => { newSocket.on('connect_error', (error) => {
console.error('Connection error:', error); console.error('Connection error:', error);
connectAttempts.current += 1; connectAttempts.current += 1;
isConnecting.current = false;
if (connectAttempts.current >= maxAttempts) { if (connectAttempts.current >= maxAttempts) {
console.error('Max connection attempts reached, giving up'); console.error('Max connection attempts reached, giving up');
@ -53,23 +64,39 @@ export const SocketProvider = ({ children }) => {
setSocket(newSocket); setSocket(newSocket);
} catch (err) { } catch (err) {
console.error('Error creating socket connection:', err); console.error('Error creating socket connection:', err);
isConnecting.current = false;
} }
}, [socket]); }, [socket]);
// Disconnect socket useEffect(() => {
if (!socket && !isConnecting.current) {
connect();
}
return () => {
pendingEventHandlers.current = {};
};
}, [connect, socket]);
const disconnect = useCallback(() => { const disconnect = useCallback(() => {
if (socket) { if (socket) {
socket.disconnect(); socket.disconnect();
setSocket(null); setSocket(null);
setConnected(false); setConnected(false);
console.log('Socket manually disconnected'); console.log('Socket manually disconnected');
pendingEventHandlers.current = {};
} }
}, [socket]); }, [socket]);
// Send event through socket
const send = useCallback((event, data) => { const send = useCallback((event, data) => {
if (!socket || !connected) { if (!socket) {
console.warn(`Cannot send event "${event}": socket not connected`); console.warn(`Cannot send event "${event}": socket not connected. Auto-connecting...`);
connect();
return false;
}
if (!connected) {
console.warn(`Socket exists but not connected when sending "${event}". Waiting for connection...`);
return false; return false;
} }
@ -80,20 +107,41 @@ export const SocketProvider = ({ children }) => {
console.error(`Error sending event "${event}":`, err); console.error(`Error sending event "${event}":`, err);
return false; return false;
} }
}, [socket, connected]); }, [socket, connected, connect]);
// Register event listener
const on = useCallback((event, callback) => { const on = useCallback((event, callback) => {
if (!socket) { if (!socket) {
console.warn(`Cannot listen for event "${event}": socket not initialized`); console.log(`Deferring registration for event "${event}" until socket is ready`);
return () => {};
if (!pendingEventHandlers.current[event]) {
pendingEventHandlers.current[event] = [];
}
pendingEventHandlers.current[event].push(callback);
if (!isConnecting.current) {
connect();
}
return () => {
if (pendingEventHandlers.current[event]) {
const index = pendingEventHandlers.current[event].indexOf(callback);
if (index > -1) {
pendingEventHandlers.current[event].splice(index, 1);
}
}
};
} }
socket.on(event, callback); socket.on(event, callback);
return () => socket.off(event, callback);
}, [socket]);
// Clean up socket on component unmount return () => {
if (socket) {
socket.off(event, callback);
}
};
}, [socket, connect]);
useEffect(() => { useEffect(() => {
return () => { return () => {
if (socket) { if (socket) {
@ -102,15 +150,18 @@ export const SocketProvider = ({ children }) => {
}; };
}, [socket]); }, [socket]);
const contextValue = {
socket,
connected,
connect,
disconnect,
send,
on,
isConnecting: isConnecting.current
};
return ( return (
<SocketContext.Provider value={{ <SocketContext.Provider value={contextValue}>
socket,
connected,
connect,
disconnect,
send,
on
}}>
{children} {children}
</SocketContext.Provider> </SocketContext.Provider>
); );

View File

@ -6,7 +6,13 @@ import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faMessage, faMusic, faHeadphones, faClock, faCrown} from "@fortawesome/free-solid-svg-icons"; import {faMessage, faMusic, faHeadphones, faClock, faCrown} from "@fortawesome/free-solid-svg-icons";
export const Game = () => { export const Game = () => {
const {send, on, socket} = useContext(SocketContext); const {send, on, socket, connected, connect} = useContext(SocketContext);
useEffect(() => {
if (!connected) {
connect();
}
}, [connected, connect]);
const [role, setRole] = useState(null); const [role, setRole] = useState(null);
const [round, setRound] = useState(1); const [round, setRound] = useState(1);
@ -29,6 +35,8 @@ export const Game = () => {
const timerIntervalRef = useRef(null); const timerIntervalRef = useRef(null);
useEffect(() => { useEffect(() => {
if (!connected) return;
const eventHandlers = { const eventHandlers = {
"roles-assigned": (roles) => { "roles-assigned": (roles) => {
const myRole = roles[socket?.id]; const myRole = roles[socket?.id];
@ -110,11 +118,13 @@ export const Game = () => {
([event, handler]) => on(event, handler) ([event, handler]) => on(event, handler)
); );
send("get-room-users"); if (connected) {
send("check-host-status"); send("get-room-users");
send("check-host-status");
}
return () => cleanupFunctions.forEach(cleanup => cleanup()); return () => cleanupFunctions.forEach(cleanup => cleanup());
}, [socket, on, send, role, currentSong, phase]); }, [socket, on, send, role, currentSong, phase, connected]);
useEffect(() => { useEffect(() => {
if (timerIntervalRef.current) clearInterval(timerIntervalRef.current); if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);

View File

@ -9,10 +9,16 @@ import {useContext, useState, useEffect} from "react";
export const Home = () => { export const Home = () => {
const {setCurrentState} = useContext(StateContext); const {setCurrentState} = useContext(StateContext);
const {connect, send, on} = useContext(SocketContext); const {connect, send, on, connected} = useContext(SocketContext);
const [homeState, setHomeState] = useState("initial"); // initial, joining, creating const [homeState, setHomeState] = useState("initial"); // initial, joining, creating
const [error, setError] = useState(""); const [error, setError] = useState("");
useEffect(() => {
if (!connected) {
connect();
}
}, [connected, connect]);
useEffect(() => { useEffect(() => {
connect(); connect();