fix: properly clean up voice session resources on disconnect

- Add resetRealtimeSessionState() function to reset session state
- Store and stop media stream from permission request to prevent resource leak
- Call reset function when voice session disconnects
This commit is contained in:
weishu
2026-01-19 19:14:46 +08:00
parent a928e82db2
commit 8a89d23e1b
2 changed files with 11 additions and 2 deletions
+5
View File
@@ -38,6 +38,11 @@ export async function stopRealtimeSession() {
}
}
export function resetRealtimeSessionState() {
currentSessionId = null
voiceSessionStarted = false
}
export function registerVoiceSession(session: VoiceSession) {
if (voiceSession) {
console.warn('[Voice] Voice session already registered, replacing with new one')
+6 -2
View File
@@ -1,6 +1,6 @@
import { useEffect, useRef, useCallback, useState } from 'react'
import { useConversation } from '@elevenlabs/react'
import { registerVoiceSession } from './RealtimeSession'
import { registerVoiceSession, resetRealtimeSessionState } from './RealtimeSession'
import { realtimeClientTools, registerSessionStore } from './realtimeClientTools'
import { fetchVoiceToken } from '@/api/voice'
import type { VoiceSession, VoiceSessionConfig, ConversationStatus, StatusCallback } from './types'
@@ -35,12 +35,15 @@ class RealtimeVoiceSessionImpl implements VoiceSession {
statusCallback?.('connecting')
// Request microphone permission first
let permissionStream: MediaStream | null = null
try {
await navigator.mediaDevices.getUserMedia({ audio: true })
permissionStream = await navigator.mediaDevices.getUserMedia({ audio: true })
} catch (error) {
console.error('[Voice] Failed to get microphone permission:', error)
statusCallback?.('error', 'Microphone permission denied')
throw error
} finally {
permissionStream?.getTracks().forEach((track) => track.stop())
}
// Fetch conversation token from server
@@ -169,6 +172,7 @@ export function RealtimeVoiceSession({
const handleDisconnect = useCallback(() => {
if (DEBUG) console.log('[Voice] Realtime session disconnected')
resetRealtimeSessionState()
onStatusChange?.('disconnected')
}, [onStatusChange])