Socket IO EventListeners no longer called on Socket IO Client reconnection in ReactJS #4612
-
If I restart my socket io server, the socket io client on the browser side reconnects successfully but registered events are no longer called no matter what. I am using a single instance of socket io in the whole of my react app in a filed called socket_io.js file which is imported into a number of different components. Here is the content of my socket_io.js singleton file: import { useState, useEffect } from 'react';
import io from "socket.io-client";
import {
getSocketIOEventListeners,
setSocketIOEventListeners,
} from './redux/event_slices';
import { useSelector, useDispatch } from 'react-redux';
const defaultUrl ='http://localhost:8000';
const defaultOptions = { transports: ["websocket"] }
let defaultSocketIO;
if (!defaultSocketIO) {
defaultSocketIO = io(defaultUrl, defaultOptions);
}
const useSocket = (_url = defaultUrl, _options = defaultOptions) => {
const [socket] = useState(defaultSocketIO);
const listeners = useSelector(getSocketIOEventListeners);
const dispatch = useDispatch();
const [disconnected, setDisconnected] = useState(false);
const connectJustOnce = (listener) => {
if (!socket?.hasListeners(listener.event)) {
socket?.on(listener.event, listener.callback);
}
}
const connectListeners = () => {
socket?.offAny();
listeners.forEach((listener) => connectJustOnce(listener));
}
useEffect(() => {
connectListeners();
return () => {
socket?.offAny();
}
}, [listeners]);
useEffect(() => {
if (!socket?.hasListeners("connect")) {
socket?.on('connect', () => {
console.log('===Connected===');
connectListeners(); // I had to attempt this because on automatic re-connection existing event handlers don't get called but even at that the problem still persists so this doesn't even solve my problem
});
}
if (!socket?.hasListeners("disconnect")) {
socket?.on('disconnect', () => {
setDisconnected(true);
console.log('===Disconnected===');
socket?.offAny();
});
}
if (!socket?.hasListeners("reconnect")) {
socket?.on('reconnect', () => {
console.log("===Reconnected===");
connectListeners();
});
}
}, [socket]);
const addSocketIOEventListener = (event, callback) => {
let listenersCopy = [...listeners];
let existingEvent = listenersCopy.find(x => x?.event === event);
if (!existingEvent) {
listenersCopy.push({ event, callback });
dispatch(setSocketIOEventListeners(listenersCopy));
}
}
const removeSocketIOEventListener = (event, callback) => {
socket?.off(event, callback);
let listenersCopy = [...listeners];
let filtered = listenersCopy.filter((listener) => listener.event !== event);
dispatch(setSocketIOEventListeners(filtered));
}
return {
socket,
addSocketIOEventListener,
removeSocketIOEventListener
}
}
export default useSocket; Here is one of the components called MessageView.js that imported the above singleton for use as follows: import useSocket from '../socket_io.js';
export default function MessageView(props){
const { addSocketIOEventListener, removeSocketIOEventListener } = useSocket();
let messageHandler=(data)=>{
//No longer called when socket io reconnects
}
useEffect(()=>{
addSocketIOEventListener('messages' ,messageHandler);
return ()=>{
removeSocketIOEventListener('messages', messageHandler);
},[]);
} My Socket IO Client is What can I do to solve this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Hi! Is there a reason why you add/remove all listeners upon connection? Also, delaying event registration (the |
Beta Was this translation helpful? Give feedback.
-
Hi! Please check our React guide: https://socket.io/how-to/use-with-react |
Beta Was this translation helpful? Give feedback.
Hi! Please check our React guide: https://socket.io/how-to/use-with-react