fix(webapp): ignore stale client stream sessions

This commit is contained in:
2026-03-29 17:30:00 +00:00
parent 360e923987
commit 2044754666

View File

@@ -766,6 +766,19 @@ const clearClientStream = () => {
setClientStreamMode('none'); setClientStreamMode('none');
}; };
const hasReusableClientStreamSession = (streamSessionId) =>
Boolean(streamSessionId && (remoteStreams.has(streamSessionId) || streamTimers.has(streamSessionId)));
const removeCameraSessionMapping = (streamSessionId) => {
if (!streamSessionId) return;
patchAppState((state) => ({
cameraSessions: Object.fromEntries(
Object.entries(state.cameraSessions || {}).filter(([, sessionId]) => sessionId !== streamSessionId)
)
}));
};
const getLinkedCamera = (cameraDeviceId) => const getLinkedCamera = (cameraDeviceId) =>
getAppState().linkedCameras.find((camera) => camera.cameraDeviceId === cameraDeviceId); getAppState().linkedCameras.find((camera) => camera.cameraDeviceId === cameraDeviceId);
@@ -1034,6 +1047,7 @@ const teardownPeerConnection = (streamSessionId) => {
pendingCandidatesMap.clear(); pendingCandidatesMap.clear();
connectedPeers.clear(); connectedPeers.clear();
setConnectedStreamSessionIds(); setConnectedStreamSessionIds();
setAppState({ cameraSessions: {} });
clearClientStream(); clearClientStream();
return; return;
} }
@@ -1046,6 +1060,7 @@ const teardownPeerConnection = (streamSessionId) => {
pendingCandidatesMap.delete(streamSessionId); pendingCandidatesMap.delete(streamSessionId);
connectedPeers.delete(streamSessionId); connectedPeers.delete(streamSessionId);
setConnectedStreamSessionIds(); setConnectedStreamSessionIds();
removeCameraSessionMapping(streamSessionId);
if (getAppState().activeStreamSessionId === streamSessionId) { if (getAppState().activeStreamSessionId === streamSessionId) {
clearClientStream(); clearClientStream();
@@ -2101,19 +2116,29 @@ const actions = {
}, },
selectCamera(cameraDeviceId) { selectCamera(cameraDeviceId) {
const sessions = getAppState().cameraSessions || {}; const currentState = getAppState();
const sessions = currentState.cameraSessions || {};
const existingSessionId = sessions[cameraDeviceId] || null;
const reusableSessionId = hasReusableClientStreamSession(existingSessionId) ? existingSessionId : null;
if (currentState.activeCameraDeviceId !== cameraDeviceId || currentState.activeStreamSessionId !== reusableSessionId) {
clearClientStream();
}
setAppState({ setAppState({
activeCameraDeviceId: cameraDeviceId, activeCameraDeviceId: cameraDeviceId,
activeStreamSessionId: sessions[cameraDeviceId] || null, activeStreamSessionId: reusableSessionId,
openLinkedCameraMenuId: null openLinkedCameraMenuId: null
}); });
void actions.requestStream(cameraDeviceId); if (reusableSessionId) {
attachClientStreamToElement();
attachClientStreamToElement(); setClientStreamMode(remoteStreams.has(reusableSessionId) ? 'video' : 'connecting');
if (!getAppState().activeStreamSessionId) { return;
setClientStreamMode('connecting');
} }
setClientStreamMode('connecting');
void actions.requestStream(cameraDeviceId);
}, },
closeStreamViewer() { closeStreamViewer() {