2024-01-25 23:27:53 +08:00
|
|
|
import { useEffect, useRef } from 'react';
|
2024-04-01 20:36:28 +08:00
|
|
|
import { useMutation } from '@apollo/client';
|
|
|
|
import { UPDATE_CONNECTION_ALIVE_AT } from './mutations';
|
2024-08-29 04:55:57 +08:00
|
|
|
import {
|
|
|
|
getStatus,
|
|
|
|
handleAudioStatsEvent,
|
|
|
|
} from '/imports/ui/components/connection-status/service';
|
2024-07-05 04:26:09 +08:00
|
|
|
import connectionStatus from '../../core/graphql/singletons/connectionStatus';
|
2023-12-06 00:12:12 +08:00
|
|
|
|
2024-07-09 01:14:30 +08:00
|
|
|
import getBaseUrl from '/imports/ui/core/utils/getBaseUrl';
|
2024-08-21 21:05:37 +08:00
|
|
|
import useCurrentUser from '../../core/hooks/useCurrentUser';
|
2024-07-09 01:14:30 +08:00
|
|
|
|
2023-12-05 22:18:45 +08:00
|
|
|
const ConnectionStatus = () => {
|
2024-07-05 04:26:09 +08:00
|
|
|
const STATS_INTERVAL = window.meetingClientSettings.public.stats.interval;
|
2024-04-01 20:36:28 +08:00
|
|
|
const networkRttInMs = useRef(0); // Ref to store the last rtt
|
2024-01-25 23:27:53 +08:00
|
|
|
const timeoutRef = useRef(null);
|
|
|
|
|
2024-04-01 20:36:28 +08:00
|
|
|
const [updateConnectionAliveAtM] = useMutation(UPDATE_CONNECTION_ALIVE_AT);
|
2023-12-05 22:18:45 +08:00
|
|
|
|
2024-08-21 21:05:37 +08:00
|
|
|
const {
|
|
|
|
data,
|
|
|
|
} = useCurrentUser((u) => ({
|
|
|
|
userId: u.userId,
|
|
|
|
avatar: u.avatar,
|
|
|
|
isModerator: u.isModerator,
|
|
|
|
color: u.color,
|
2024-08-28 22:08:30 +08:00
|
|
|
currentlyInMeeting: u.currentlyInMeeting,
|
2024-08-21 21:05:37 +08:00
|
|
|
}));
|
|
|
|
|
2024-04-01 20:36:28 +08:00
|
|
|
const handleUpdateConnectionAliveAt = () => {
|
|
|
|
const startTime = performance.now();
|
2024-07-05 04:26:09 +08:00
|
|
|
fetch(
|
2024-07-09 01:14:30 +08:00
|
|
|
`${getBaseUrl()}/ping`,
|
2024-07-05 04:26:09 +08:00
|
|
|
{ signal: AbortSignal.timeout(STATS_INTERVAL) },
|
|
|
|
)
|
|
|
|
.then((res) => {
|
|
|
|
if (res.ok && res.status === 200) {
|
|
|
|
const rttLevels = window.meetingClientSettings.public.stats.rtt;
|
|
|
|
const endTime = performance.now();
|
2024-08-15 03:52:11 +08:00
|
|
|
const networkRtt = Math.round(endTime - startTime);
|
2024-07-05 04:26:09 +08:00
|
|
|
networkRttInMs.current = networkRtt;
|
|
|
|
updateConnectionAliveAtM({
|
|
|
|
variables: {
|
|
|
|
networkRttInMs: networkRtt,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const rttStatus = getStatus(rttLevels, networkRtt);
|
2024-08-15 03:52:11 +08:00
|
|
|
connectionStatus.setRttValue(networkRtt);
|
2024-07-05 04:26:09 +08:00
|
|
|
connectionStatus.setRttStatus(rttStatus);
|
|
|
|
connectionStatus.setLastRttRequestSuccess(true);
|
2024-08-21 21:05:37 +08:00
|
|
|
|
|
|
|
if (Object.keys(rttLevels).includes(rttStatus)) {
|
|
|
|
connectionStatus.addUserNetworkHistory(
|
|
|
|
data,
|
|
|
|
rttStatus,
|
|
|
|
Date.now(),
|
|
|
|
);
|
|
|
|
}
|
2024-07-05 04:26:09 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
connectionStatus.setLastRttRequestSuccess(false);
|
|
|
|
// gets the worst status
|
|
|
|
connectionStatus.setRttStatus('critical');
|
|
|
|
})
|
|
|
|
.finally(() => {
|
|
|
|
if (timeoutRef.current) {
|
|
|
|
clearTimeout(timeoutRef.current);
|
|
|
|
}
|
2023-12-05 22:18:45 +08:00
|
|
|
|
2024-07-05 04:26:09 +08:00
|
|
|
timeoutRef.current = setTimeout(() => {
|
|
|
|
handleUpdateConnectionAliveAt();
|
|
|
|
}, STATS_INTERVAL);
|
|
|
|
});
|
2023-12-05 22:18:45 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
useEffect(() => {
|
2024-04-01 20:36:28 +08:00
|
|
|
// Delay first connectionAlive to avoid high RTT misestimation
|
|
|
|
// due to initial subscription and mutation traffic at client render
|
|
|
|
timeoutRef.current = setTimeout(() => {
|
|
|
|
handleUpdateConnectionAliveAt();
|
|
|
|
}, STATS_INTERVAL / 2);
|
2024-05-29 21:26:11 +08:00
|
|
|
|
|
|
|
const STATS_ENABLED = window.meetingClientSettings.public.stats.enabled;
|
|
|
|
|
|
|
|
if (STATS_ENABLED) {
|
2024-09-13 21:15:35 +08:00
|
|
|
// This will generate metrics usage to determine alert statuses based
|
|
|
|
// on WebRTC stats
|
2024-08-29 04:55:57 +08:00
|
|
|
window.addEventListener('audiostats', handleAudioStatsEvent);
|
2024-05-29 21:26:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return () => {
|
2024-08-29 04:55:57 +08:00
|
|
|
window.removeEventListener('audiostats', handleAudioStatsEvent);
|
|
|
|
|
2024-07-17 22:37:04 +08:00
|
|
|
if (timeoutRef.current) {
|
|
|
|
clearTimeout(timeoutRef.current);
|
|
|
|
}
|
2024-05-29 21:26:11 +08:00
|
|
|
};
|
2023-12-05 22:18:45 +08:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
export default ConnectionStatus;
|