diff --git a/src/components/Shell/ConnectionTestResults.tsx b/src/components/Shell/ConnectionTestResults.tsx
index e1fd3ee..7f4c83c 100644
--- a/src/components/Shell/ConnectionTestResults.tsx
+++ b/src/components/Shell/ConnectionTestResults.tsx
@@ -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 (
+
+
+
+ Server connection failed
+
+
+ )
+ }
+
+ if (trackerConnection !== TrackerConnection.CONNECTED) {
return (
{
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 },
}
}
diff --git a/src/contexts/ShellContext.ts b/src/contexts/ShellContext.ts
index da920c0..16704e6 100644
--- a/src/contexts/ShellContext.ts
+++ b/src/contexts/ShellContext.ts
@@ -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({
setPeerAudios: () => {},
customUsername: '',
setCustomUsername: () => {},
- connectionTestResults: { hasHost: false, hasRelay: false, hasTracker: false },
+ connectionTestResults: {
+ hasHost: false,
+ hasRelay: false,
+ trackerConnection: TrackerConnection.SEARCHING,
+ },
})
diff --git a/src/services/ConnectionTest/ConnectionTest.ts b/src/services/ConnectionTest/ConnectionTest.ts
index f076287..1523f04 100644
--- a/src/services/ConnectionTest/ConnectionTest.ts
+++ b/src/services/ConnectionTest/ConnectionTest.ts
@@ -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
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
}
}