🩹(frontend) fix connection warmup with WebSocket pre-authentication

Connection warmup wasn't working properly - only works when trying to
establish WebSocket first, then workaround kicks in. Call WebSocket
endpoint without auth info expecting 401 error, but enough to initiate
cache for subsequent WebSocket functionality.

Scope this **dirty** trick to Firefox users only. Haven't figured out
how to detect proxy from JS code simply.

Tested in staging and works on our constrained WiFi.
This commit is contained in:
lebaudantoine
2025-07-24 15:52:34 +02:00
parent 3d245c3bd4
commit be63993ba2
5 changed files with 42 additions and 8 deletions

View File

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

View File

@@ -492,6 +492,11 @@ class Base(Configuration):
),
"url": values.Value(environ_name="LIVEKIT_API_URL", environ_prefix=None),
}
LIVEKIT_ENABLE_FIREFOX_PROXY_WORKAROUND = values.BooleanValue(
environ_name="LIVEKIT_ENABLE_FIREFOX_PROXY_WORKAROUND",
environ_prefix=None,
default=False,
)
LIVEKIT_VERIFY_SSL = values.BooleanValue(
True, environ_name="LIVEKIT_VERIFY_SSL", environ_prefix=None
)

View File

@@ -39,6 +39,7 @@ export interface ApiConfig {
manifest_link?: string
livekit: {
url: string
enable_firefox_proxy_workaround: boolean
}
}

View File

@@ -25,6 +25,7 @@ import { navigateTo } from '@/navigation/navigateTo'
import { MediaDeviceErrorAlert } from './MediaDeviceErrorAlert'
import { usePostHog } from 'posthog-js/react'
import { useConfig } from '@/api/useConfig'
import { isFireFox } from '@/utils/livekit'
export const Conference = ({
roomId,
@@ -103,17 +104,40 @@ export const Conference = ({
* 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 workaround - issue is reproducible on LiveKit's demo app.
* It should cache DNS and TLS keys.
*/
const prepareConnection = async () => {
if (!apiConfig || isConnectionWarmedUp) return
await room.prepareConnection(apiConfig.livekit.url)
if (isFireFox() && apiConfig.livekit.enable_firefox_proxy_workaround) {
try {
const wssUrl =
apiConfig.livekit.url
.replace('https://', 'wss://')
.replace(/\/$/, '') + '/rtc'
/**
* FIREFOX + PROXY WORKAROUND:
*
* Issue: On Firefox behind proxy configurations, WebSocket signaling fails to establish.
* Symptom: Client receives HTTP 200 instead of expected 101 (Switching Protocols).
* Root Cause: Certificate/security issue where the initial request is considered unsecure.
*
* Solution: Pre-establish a WebSocket connection to the signaling server, which fails.
* This "primes" the connection, allowing subsequent WebSocket establishments to work correctly.
*
* Note: This issue is reproducible on LiveKit's demo app.
* Reference: livekit-examples/meet/issues/466
*/
const ws = new WebSocket(wssUrl)
// 401 unauthorized response is expected
ws.onerror = () => ws.readyState <= 1 && ws.close()
} catch (e) {
console.debug('Firefox WebSocket workaround failed.', e)
}
}
setIsConnectionWarmedUp(true)
}
prepareConnection()

View File

@@ -52,6 +52,7 @@ backend:
{{- end }}
{{- end }}
LIVEKIT_API_URL: https://livekit.127.0.0.1.nip.io/
LIVEKIT_ENABLE_FIREFOX_PROXY_WORKAROUND: True
ALLOW_UNREGISTERED_ROOMS: False
FRONTEND_SILENCE_LIVEKIT_DEBUG: False
FRONTEND_SUPPORT: "{'id': '58ea6697-8eba-4492-bc59-ad6562585041', 'help_article_transcript': 'https://lasuite.crisp.help/fr/article/visio-transcript-1sjq43x', 'help_article_recording': 'https://lasuite.crisp.help/fr/article/visio-enregistrement-wgc8o0', 'help_article_more_tools': 'https://lasuite.crisp.help/fr/article/visio-tools-bvxj23'}"