mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-04-28 05:47:52 +00:00
153 lines
5.1 KiB
TypeScript
153 lines
5.1 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import {
|
|
getBaseApiReactSocket,
|
|
pauseAllQueues,
|
|
resumeAllQueues,
|
|
} from '../../App';
|
|
import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events';
|
|
|
|
export const WebSocketActive = ({ myAddress, setIsLoadingGroups }) => {
|
|
const socketRef = useRef(null); // WebSocket reference
|
|
const timeoutIdRef = useRef(null); // Timeout ID reference
|
|
const groupSocketTimeoutRef = useRef(null); // Group Socket Timeout reference
|
|
const initiateRef = useRef(null);
|
|
const forceCloseWebSocket = () => {
|
|
if (socketRef.current) {
|
|
clearTimeout(timeoutIdRef.current);
|
|
clearTimeout(groupSocketTimeoutRef.current);
|
|
socketRef.current.close(1000, 'forced');
|
|
socketRef.current = null;
|
|
}
|
|
};
|
|
|
|
const logoutEventFunc = () => {
|
|
forceCloseWebSocket();
|
|
};
|
|
|
|
useEffect(() => {
|
|
subscribeToEvent('logout-event', logoutEventFunc);
|
|
|
|
return () => {
|
|
unsubscribeFromEvent('logout-event', logoutEventFunc);
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!myAddress) return; // Only proceed if myAddress is set
|
|
|
|
const pingHeads = () => {
|
|
try {
|
|
if (socketRef.current?.readyState === WebSocket.OPEN) {
|
|
socketRef.current.send('ping');
|
|
timeoutIdRef.current = setTimeout(() => {
|
|
if (socketRef.current) {
|
|
socketRef.current.close();
|
|
clearTimeout(groupSocketTimeoutRef.current);
|
|
}
|
|
}, 5000); // Close if no pong in 5 seconds
|
|
}
|
|
} catch (error) {
|
|
console.error('Error during ping:', error);
|
|
}
|
|
};
|
|
|
|
const initWebsocketMessageGroup = async () => {
|
|
forceCloseWebSocket(); // Ensure we close any existing connection
|
|
const currentAddress = myAddress;
|
|
|
|
try {
|
|
if (!initiateRef.current) {
|
|
setIsLoadingGroups(true);
|
|
pauseAllQueues();
|
|
}
|
|
const socketLink = `${getBaseApiReactSocket()}/websockets/chat/active/${currentAddress}?encoding=BASE64&haschatreference=false`;
|
|
socketRef.current = new WebSocket(socketLink);
|
|
|
|
socketRef.current.onopen = () => {
|
|
setTimeout(pingHeads, 50); // Initial ping
|
|
};
|
|
|
|
socketRef.current.onmessage = (e) => {
|
|
try {
|
|
if (e.data === 'pong') {
|
|
clearTimeout(timeoutIdRef.current);
|
|
groupSocketTimeoutRef.current = setTimeout(pingHeads, 45000); // Ping every 45 seconds
|
|
} else {
|
|
if (!initiateRef.current) {
|
|
setIsLoadingGroups(false);
|
|
initiateRef.current = true;
|
|
resumeAllQueues();
|
|
}
|
|
const data = JSON.parse(e.data);
|
|
const copyGroups = [...(data?.groups || [])];
|
|
const findIndex = copyGroups?.findIndex(
|
|
(item) => item?.groupId === 0
|
|
);
|
|
if (findIndex !== -1) {
|
|
copyGroups[findIndex] = {
|
|
...(copyGroups[findIndex] || {}),
|
|
groupId: '0',
|
|
};
|
|
}
|
|
const filteredGroups = copyGroups;
|
|
const sortedGroups = filteredGroups.sort(
|
|
(a, b) => (b.timestamp || 0) - (a.timestamp || 0)
|
|
);
|
|
const sortedDirects = (data?.direct || [])
|
|
.filter(
|
|
(item) =>
|
|
item?.name !== 'extension-proxy' &&
|
|
item?.address !== 'QSMMGSgysEuqDCuLw3S4cHrQkBrh3vP3VH'
|
|
)
|
|
.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
|
|
|
window
|
|
.sendMessage('handleActiveGroupDataFromSocket', {
|
|
groups: sortedGroups,
|
|
directs: sortedDirects,
|
|
})
|
|
.catch((error) => {
|
|
// TODO translate
|
|
console.error(
|
|
'Failed to handle active group data from socket:',
|
|
error.message || 'An error occurred'
|
|
);
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Error parsing onmessage data:', error);
|
|
}
|
|
};
|
|
|
|
socketRef.current.onclose = (event) => {
|
|
clearTimeout(groupSocketTimeoutRef.current);
|
|
clearTimeout(timeoutIdRef.current);
|
|
console.warn(`WebSocket closed: ${event.reason || 'unknown reason'}`);
|
|
if (event.reason !== 'forced' && event.code !== 1000) {
|
|
setTimeout(() => initWebsocketMessageGroup(), 10000); // Retry after 10 seconds
|
|
}
|
|
};
|
|
|
|
socketRef.current.onerror = (error) => {
|
|
console.error('WebSocket error:', error);
|
|
clearTimeout(groupSocketTimeoutRef.current);
|
|
clearTimeout(timeoutIdRef.current);
|
|
if (socketRef.current) {
|
|
socketRef.current.close();
|
|
}
|
|
};
|
|
} catch (error) {
|
|
console.error('Error initializing WebSocket:', error);
|
|
}
|
|
};
|
|
|
|
initWebsocketMessageGroup(); // Initialize WebSocket on component mount
|
|
|
|
return () => {
|
|
forceCloseWebSocket(); // Clean up WebSocket on component unmount
|
|
};
|
|
}, [myAddress]);
|
|
|
|
return null;
|
|
};
|