🐛(frontend) add LiveKit connection warmup for Firefox+proxy fixes

Implement HTTPS prefetch before joining rooms to resolve WebSocket
handshake failures where Firefox+proxy returns HTTP 200 instead of 101.

Reproduced locally with Squid container. No proxy configuration fixes
found - HTTPS warmup is only working workaround. Issue doesn't occur
when signaling server shares webapp domain, making warmup unnecessary.

Use HEAD request to minimize bandwidth.
This commit is contained in:
lebaudantoine
2025-07-23 11:50:02 +02:00
parent d44b45b6aa
commit 387bc2e1f4
3 changed files with 40 additions and 2 deletions

View File

@@ -50,6 +50,7 @@ def get_frontend_configuration(request):
else None,
"default_country": settings.ROOM_TELEPHONY_DEFAULT_COUNTRY,
},
"livekit": {"url": settings.LIVEKIT_CONFIGURATION["url"]},
}
frontend_configuration.update(settings.FRONTEND_CONFIGURATION)
return Response(frontend_configuration)

View File

@@ -37,6 +37,9 @@ export interface ApiConfig {
default_country?: string
}
manifest_link?: string
livekit: {
url: string
}
}
const fetchConfig = (): Promise<ApiConfig> => {

View File

@@ -24,6 +24,7 @@ import { LocalUserChoices } from '@/stores/userChoices'
import { navigateTo } from '@/navigation/navigateTo'
import { MediaDeviceErrorAlert } from './MediaDeviceErrorAlert'
import { usePostHog } from 'posthog-js/react'
import { useConfig } from '@/api/useConfig'
export const Conference = ({
roomId,
@@ -37,12 +38,15 @@ export const Conference = ({
initialRoomData?: ApiRoom
}) => {
const posthog = usePostHog()
const { data: apiConfig } = useConfig()
useEffect(() => {
posthog.capture('visit-room', { slug: roomId })
}, [roomId, posthog])
const fetchKey = [keys.room, roomId]
const [isConnectionWarmedUp, setIsConnectionWarmedUp] = useState(false)
const {
mutateAsync: createRoom,
status: createStatus,
@@ -53,6 +57,36 @@ export const Conference = ({
},
})
/**
* Warm up connection to LiveKit server before joining room
* This prefetch helps reduce initial connection latency by establishing
* an early HTTP connection to the WebRTC signaling server
*
* FIREFOX + PROXY WORKAROUND:
* On Firefox behind proxy configurations, WebSocket signaling fails to establish.
* Client receives HTTP 200 instead of expected 101 (Switching Protocols).
* This appears to be a certificate/security issue where the initial request
* is considered unsecure. By first calling the signaling server via HTTPS,
* subsequent WebSocket establishment works correctly in these setups.
* This is a temporary workaround - issue is reproducible on LiveKit's demo app.
*/
useEffect(() => {
const warmUpLivekitConnection = async () => {
if (isConnectionWarmedUp || !apiConfig) return
try {
// Make HTTPS request to establish secure connection
// This resolves Firefox+proxy WebSocket handshake issues
await fetch(apiConfig.livekit.url)
setIsConnectionWarmedUp(true)
} catch (error) {
// Don't block room connection if warmup fails
console.warn('LiveKit connection warmup failed:', error)
setIsConnectionWarmedUp(true)
}
}
warmUpLivekitConnection()
}, [isConnectionWarmedUp, apiConfig])
const {
status: fetchStatus,
isError: isFetchError,
@@ -125,9 +159,9 @@ export const Conference = ({
<Screen header={false} footer={false}>
<LiveKitRoom
room={room}
serverUrl={data?.livekit?.url}
serverUrl={apiConfig?.livekit.url}
token={data?.livekit?.token}
connect={true}
connect={isConnectionWarmedUp}
audio={userConfig.audioEnabled}
video={
userConfig.videoEnabled && {