forked from Shiloh/remnantchat
feat(connection-test): display failed tracker connections (#129)
This commit is contained in:
parent
291ed0c2b9
commit
f67dbb60d3
@ -3,6 +3,9 @@ import Tooltip from '@mui/material/Tooltip'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import Circle from '@mui/icons-material/FiberManualRecord'
|
||||
import { Box } from '@mui/system'
|
||||
import ReportIcon from '@mui/icons-material/Report'
|
||||
|
||||
import { TrackerConnection } from 'services/ConnectionTest/ConnectionTest'
|
||||
|
||||
import { ConnectionTestResults as IConnectionTestResults } from './useConnectionTest'
|
||||
|
||||
@ -10,9 +13,22 @@ interface ConnectionTestResultsProps {
|
||||
connectionTestResults: IConnectionTestResults
|
||||
}
|
||||
export const ConnectionTestResults = ({
|
||||
connectionTestResults: { hasHost, hasRelay, hasTracker },
|
||||
connectionTestResults: { hasHost, hasRelay, trackerConnection },
|
||||
}: ConnectionTestResultsProps) => {
|
||||
if (!hasTracker) {
|
||||
if (trackerConnection === TrackerConnection.FAILED) {
|
||||
return (
|
||||
<Typography variant="subtitle2">
|
||||
<Box
|
||||
sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}
|
||||
>
|
||||
<ReportIcon color="error" sx={{ mr: 1 }} />
|
||||
<span>Server connection failed</span>
|
||||
</Box>
|
||||
</Typography>
|
||||
)
|
||||
}
|
||||
|
||||
if (trackerConnection !== TrackerConnection.CONNECTED) {
|
||||
return (
|
||||
<Typography variant="subtitle2">
|
||||
<Box
|
||||
|
@ -16,6 +16,7 @@ import { PeerListHeader } from 'components/Shell/PeerListHeader'
|
||||
import { Username } from 'components/Username/Username'
|
||||
import { AudioState, Peer } from 'models/chat'
|
||||
import { PeerConnectionType } from 'services/PeerRoom/PeerRoom'
|
||||
import { TrackerConnection } from 'services/ConnectionTest/ConnectionTest'
|
||||
import { routes } from 'config/routes'
|
||||
|
||||
import { PeerListItem } from './PeerListItem'
|
||||
@ -113,7 +114,8 @@ export const PeerList = ({
|
||||
))}
|
||||
{peerList.length === 0 &&
|
||||
typeof roomId === 'string' &&
|
||||
connectionTestResults.hasTracker &&
|
||||
connectionTestResults.trackerConnection ===
|
||||
TrackerConnection.CONNECTED &&
|
||||
connectionTestResults.hasHost ? (
|
||||
<>
|
||||
<Box
|
||||
|
@ -4,12 +4,13 @@ import {
|
||||
ConnectionTest,
|
||||
ConnectionTestEvent,
|
||||
ConnectionTestEvents,
|
||||
TrackerConnection,
|
||||
} from 'services/ConnectionTest/ConnectionTest'
|
||||
|
||||
export interface ConnectionTestResults {
|
||||
hasHost: boolean
|
||||
hasRelay: boolean
|
||||
hasTracker: boolean
|
||||
trackerConnection: TrackerConnection
|
||||
}
|
||||
|
||||
const rtcPollInterval = 20 * 1000
|
||||
@ -18,7 +19,9 @@ const trackerPollInterval = 5 * 1000
|
||||
export const useConnectionTest = () => {
|
||||
const [hasHost, setHasHost] = useState(false)
|
||||
const [hasRelay, setHasRelay] = useState(false)
|
||||
const [hasTracker, setHasTracker] = useState(false)
|
||||
const [trackerConnection, setTrackerConnection] = useState(
|
||||
TrackerConnection.SEARCHING
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const checkRtcConnection = async () => {
|
||||
@ -83,14 +86,22 @@ export const useConnectionTest = () => {
|
||||
})()
|
||||
;(async () => {
|
||||
while (true) {
|
||||
const connectionTest = new ConnectionTest()
|
||||
setHasTracker(connectionTest.testTrackerConnection())
|
||||
try {
|
||||
const connectionTest = new ConnectionTest()
|
||||
const trackerConnectionTestResult =
|
||||
connectionTest.testTrackerConnection()
|
||||
|
||||
setTrackerConnection(trackerConnectionTestResult)
|
||||
} catch (e) {
|
||||
setTrackerConnection(TrackerConnection.FAILED)
|
||||
}
|
||||
|
||||
await sleep(trackerPollInterval)
|
||||
}
|
||||
})()
|
||||
}, [])
|
||||
|
||||
return {
|
||||
connectionTestResults: { hasHost, hasRelay, hasTracker },
|
||||
connectionTestResults: { hasHost, hasRelay, trackerConnection },
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { AlertOptions } from 'models/shell'
|
||||
import { AudioState, ScreenShareState, VideoState, Peer } from 'models/chat'
|
||||
import { PeerConnectionType } from 'services/PeerRoom/PeerRoom'
|
||||
import { ConnectionTestResults } from 'components/Shell/useConnectionTest'
|
||||
import { TrackerConnection } from 'services/ConnectionTest/ConnectionTest'
|
||||
|
||||
interface ShellContextProps {
|
||||
tabHasFocus: boolean
|
||||
@ -62,5 +63,9 @@ export const ShellContext = createContext<ShellContextProps>({
|
||||
setPeerAudios: () => {},
|
||||
customUsername: '',
|
||||
setCustomUsername: () => {},
|
||||
connectionTestResults: { hasHost: false, hasRelay: false, hasTracker: false },
|
||||
connectionTestResults: {
|
||||
hasHost: false,
|
||||
hasRelay: false,
|
||||
trackerConnection: TrackerConnection.SEARCHING,
|
||||
},
|
||||
})
|
||||
|
@ -8,12 +8,18 @@ export enum ConnectionTestEvents {
|
||||
HAS_RELAY_CHANGED = 'HAS_RELAY_CHANGED',
|
||||
}
|
||||
|
||||
export enum TrackerConnection {
|
||||
SEARCHING = 'SEARCHING',
|
||||
CONNECTED = 'CONNECTED',
|
||||
FAILED = 'FAILED',
|
||||
}
|
||||
|
||||
export type ConnectionTestEvent = CustomEvent<ConnectionTest>
|
||||
|
||||
const checkExperationTime = 10 * 1000
|
||||
|
||||
export class ConnectionTest extends EventTarget {
|
||||
hasTracker = false
|
||||
trackerConnection = TrackerConnection.SEARCHING
|
||||
hasHost = false
|
||||
hasRelay = false
|
||||
hasPeerReflexive = false
|
||||
@ -100,17 +106,34 @@ export class ConnectionTest extends EventTarget {
|
||||
testTrackerConnection() {
|
||||
const trackers = getTrackers()
|
||||
|
||||
const readyStates = Object.values(trackers).map(
|
||||
({ readyState }) => readyState
|
||||
const trackerSockets = Object.values(trackers)
|
||||
|
||||
if (trackerSockets.length === 0) {
|
||||
// Trystero has not yet initialized tracker sockets
|
||||
this.trackerConnection = TrackerConnection.SEARCHING
|
||||
return this.trackerConnection
|
||||
}
|
||||
|
||||
const readyStates = trackerSockets.map(({ readyState }) => readyState)
|
||||
|
||||
const haveAllTrackerConnectionsFailed = readyStates.every(
|
||||
readyState => readyState === WebSocket.CLOSED
|
||||
)
|
||||
|
||||
if (haveAllTrackerConnectionsFailed) {
|
||||
this.trackerConnection = TrackerConnection.FAILED
|
||||
throw new Error('Could not connect to a WebTorrent tracker')
|
||||
}
|
||||
|
||||
const areAnyTrackersConnected = readyStates.some(
|
||||
readyState => readyState === WebSocket.OPEN
|
||||
)
|
||||
|
||||
this.hasTracker = areAnyTrackersConnected
|
||||
this.trackerConnection = areAnyTrackersConnected
|
||||
? TrackerConnection.CONNECTED
|
||||
: TrackerConnection.SEARCHING
|
||||
|
||||
return this.hasTracker
|
||||
return this.trackerConnection
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user