Skip to content

Commit 7ac7726

Browse files
committed
Add error handling and token refresh to Media Stream
1 parent dd1804d commit 7ac7726

File tree

3 files changed

+48
-18
lines changed

3 files changed

+48
-18
lines changed

frontend/src/components/Contexts/MediaStreamContext.tsx

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,35 @@ export const MediaStreamProvider: FC<Props> = ({ children }) => {
7272
})
7373
}
7474

75+
const isTokenExpired = (token: string): boolean => {
76+
try {
77+
const payload = JSON.parse(atob(token.split('.')[1]))
78+
return Date.now() >= payload.exp * 1000
79+
} catch {
80+
return true
81+
}
82+
}
83+
7584
const createLiveKitConnection = async (config: MediaStreamConfig, cachedConfig: boolean = false) => {
85+
if (isTokenExpired(config.token)) {
86+
console.log('Token expired, refreshing config')
87+
if (!cachedConfig) {
88+
refreshRobotMediaConfig(config.robotId)
89+
return
90+
}
91+
}
92+
7693
const room = new Room()
7794

7895
window.addEventListener('unload', async () => room.disconnect())
7996

8097
room.on(RoomEvent.TrackSubscribed, (track) => addTrackToConnection(track.mediaStreamTrack, config.robotId))
98+
99+
room.on(RoomEvent.Disconnected, (reason) => {
100+
console.log('LiveKit disconnected:', reason)
101+
refreshRobotMediaConfig(config.robotId)
102+
})
103+
81104
room.on(RoomEvent.TrackUnpublished, (e) => {
82105
setMediaStreams((oldStreams) => {
83106
const streamsCopy = { ...oldStreams }
@@ -99,12 +122,24 @@ export const MediaStreamProvider: FC<Props> = ({ children }) => {
99122
})
100123

101124
if (room.state === ConnectionState.Disconnected) {
102-
room.connect(config.url, config.token)
103-
.then(() => console.log('LiveKit room status: ', JSON.stringify(room.state)))
104-
.catch((error) => {
105-
if (cachedConfig) refreshRobotMediaConfig(config.robotId)
106-
else console.error('Failed to connect to LiveKit room: ', error)
107-
})
125+
try {
126+
await room.connect(config.url, config.token)
127+
console.log('LiveKit room status: ', JSON.stringify(room.state))
128+
} catch (error) {
129+
console.error('Failed to connect to LiveKit room: ', error)
130+
if (cachedConfig) {
131+
console.log('Connection failed with cached config, refreshing...')
132+
refreshRobotMediaConfig(config.robotId)
133+
} else {
134+
setMediaStreams((oldStreams) => ({
135+
...oldStreams,
136+
[config.robotId]: {
137+
...oldStreams[config.robotId],
138+
isLoading: false,
139+
},
140+
}))
141+
}
142+
}
108143
}
109144
}
110145

@@ -146,19 +181,14 @@ export const MediaStreamProvider: FC<Props> = ({ children }) => {
146181
.then((conf: MediaStreamConfig | null | undefined) => {
147182
if (conf) addConfigToMediaStreams(conf)
148183
})
149-
.catch(() => console.log(`No media config found for robot with ID ${robotId}`))
184+
.catch((error) => console.error('Error refreshing media config:', error))
150185
}
151186

152187
return (
153-
<MediaStreamContext.Provider
154-
value={{
155-
mediaStreams,
156-
addMediaStreamConfigIfItDoesNotExist,
157-
}}
158-
>
188+
<MediaStreamContext.Provider value={{ mediaStreams, addMediaStreamConfigIfItDoesNotExist }}>
159189
{children}
160190
</MediaStreamContext.Provider>
161191
)
162192
}
163193

164-
export const useMediaStreamContext = () => useContext(MediaStreamContext)
194+
export const useMediaStream = () => useContext(MediaStreamContext)

frontend/src/components/Pages/MissionPage/MissionPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { AlertType, useAlertContext } from 'components/Contexts/AlertContext'
1111
import { useLanguageContext } from 'components/Contexts/LanguageContext'
1212
import { FailedRequestAlertContent, FailedRequestAlertListContent } from 'components/Alerts/FailedRequestAlert'
1313
import { AlertCategory } from 'components/Alerts/AlertsBanner'
14-
import { useMediaStreamContext } from 'components/Contexts/MediaStreamContext'
14+
import { useMediaStream } from 'components/Contexts/MediaStreamContext'
1515
import { StyledPage } from 'components/Styles/StyledComponents'
1616
import { InspectionDialogView } from '../InspectionReportPage/InspectionView'
1717
import { useInspectionsContext } from 'components/Contexts/InspectionsContext'
@@ -42,7 +42,7 @@ export const MissionPage = ({ missionId }: { missionId: string }) => {
4242
const [videoMediaStreams, setVideoMediaStreams] = useState<MediaStreamTrack[]>([])
4343
const [selectedMission, setSelectedMission] = useState<Mission>()
4444
const { registerEvent, connectionReady } = useSignalRContext()
45-
const { mediaStreams, addMediaStreamConfigIfItDoesNotExist } = useMediaStreamContext()
45+
const { mediaStreams, addMediaStreamConfigIfItDoesNotExist } = useMediaStream()
4646
const { selectedInspectionTask } = useInspectionsContext()
4747

4848
useEffect(() => {

frontend/src/components/Pages/RobotPage/RobotPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { useLanguageContext } from 'components/Contexts/LanguageContext'
1111
import { useAssetContext } from 'components/Contexts/AssetContext'
1212
import { StyledButton, StyledPage } from 'components/Styles/StyledComponents'
1313
import { DocumentationSection } from './Documentation'
14-
import { useMediaStreamContext } from 'components/Contexts/MediaStreamContext'
14+
import { useMediaStream } from 'components/Contexts/MediaStreamContext'
1515
import { VideoStreamSection } from '../MissionPage/MissionPage'
1616
import { useEffect, useState } from 'react'
1717
import { VideoStreamWindow } from '../MissionPage/VideoStream/VideoStreamWindow'
@@ -90,7 +90,7 @@ const StyledStatusElement = styled.div`
9090
export const RobotPage = ({ robotId }: { robotId: string }) => {
9191
const { TranslateText } = useLanguageContext()
9292
const { enabledRobots } = useAssetContext()
93-
const { mediaStreams, addMediaStreamConfigIfItDoesNotExist } = useMediaStreamContext()
93+
const { mediaStreams, addMediaStreamConfigIfItDoesNotExist } = useMediaStream()
9494
const [videoMediaStreams, setVideoMediaStreams] = useState<MediaStreamTrack[]>([])
9595
const { ongoingMissions } = useMissionsContext()
9696

0 commit comments

Comments
 (0)