mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
this is how it should have been...
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
||||||
<title>Multi Roomba Rover</title>
|
<title>Multi Roomba Rover</title>
|
||||||
<script type="module" crossorigin src="/assets/index-CAsUvZ8l.js"></script>
|
<script type="module" crossorigin src="/assets/index-BSwETZ7o.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-B1UrCI1T.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-B1UrCI1T.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import { useSocket } from '../context/SocketContext.jsx';
|
import { useSocket } from '../context/SocketContext.jsx';
|
||||||
|
|
||||||
const RETRY_DELAY_MS = 3000;
|
const RETRY_DELAY_MS = 3000;
|
||||||
|
const RATE_LIMIT_RETRY_MS = 5000;
|
||||||
|
|
||||||
function normalizeCamera(entry) {
|
function normalizeCamera(entry) {
|
||||||
if (!entry) return null;
|
if (!entry) return null;
|
||||||
@@ -33,6 +34,7 @@ export function useRoomCameraSnapshots(sourceList = []) {
|
|||||||
const entriesKey = useMemo(() => normalizedEntries.map((e) => e.key).join('|'), [normalizedEntries]);
|
const entriesKey = useMemo(() => normalizedEntries.map((e) => e.key).join('|'), [normalizedEntries]);
|
||||||
const retryTimers = useRef(new Map());
|
const retryTimers = useRef(new Map());
|
||||||
const entriesRef = useRef([]);
|
const entriesRef = useRef([]);
|
||||||
|
const subscribeState = useRef(new Map()); // id -> 'idle' | 'pending' | 'subscribed'
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
entriesRef.current = normalizedEntries;
|
entriesRef.current = normalizedEntries;
|
||||||
@@ -44,6 +46,7 @@ export function useRoomCameraSnapshots(sourceList = []) {
|
|||||||
setFeeds({});
|
setFeeds({});
|
||||||
retryTimers.current.forEach((timer) => clearTimeout(timer));
|
retryTimers.current.forEach((timer) => clearTimeout(timer));
|
||||||
retryTimers.current.clear();
|
retryTimers.current.clear();
|
||||||
|
subscribeState.current.clear();
|
||||||
}, [entriesKey]);
|
}, [entriesKey]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -109,12 +112,26 @@ export function useRoomCameraSnapshots(sourceList = []) {
|
|||||||
const requestSubscribe = (id) => {
|
const requestSubscribe = (id) => {
|
||||||
const entry = entries.find((e) => e.id === id);
|
const entry = entries.find((e) => e.id === id);
|
||||||
if (!entry) return;
|
if (!entry) return;
|
||||||
|
// Avoid spamming subscribe if already pending/subscribed.
|
||||||
|
const state = subscribeState.current.get(id) || 'idle';
|
||||||
|
if (state === 'pending' || state === 'subscribed') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subscribeState.current.set(id, 'pending');
|
||||||
socket.emit('roomCamera:subscribe', { roomCameraId: entry.id }, (resp = {}) => {
|
socket.emit('roomCamera:subscribe', { roomCameraId: entry.id }, (resp = {}) => {
|
||||||
if (resp.error) {
|
if (resp.error) {
|
||||||
|
subscribeState.current.set(id, 'idle');
|
||||||
handleStatus({ id: entry.id, error: resp.error });
|
handleStatus({ id: entry.id, error: resp.error });
|
||||||
scheduleRetry(entry.id);
|
const delay = resp.error.toLowerCase().includes('rate') ? RATE_LIMIT_RETRY_MS : RETRY_DELAY_MS;
|
||||||
|
clearRetry(entry.id);
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
retryTimers.current.delete(entry.id);
|
||||||
|
requestSubscribe(entry.id);
|
||||||
|
}, delay);
|
||||||
|
retryTimers.current.set(entry.id, timer);
|
||||||
} else {
|
} else {
|
||||||
clearRetry(entry.id);
|
clearRetry(entry.id);
|
||||||
|
subscribeState.current.set(id, 'subscribed');
|
||||||
handleStatus({ id: entry.id, stale: true });
|
handleStatus({ id: entry.id, stale: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -136,6 +153,7 @@ export function useRoomCameraSnapshots(sourceList = []) {
|
|||||||
objectUrls.current.clear();
|
objectUrls.current.clear();
|
||||||
retryTimers.current.forEach((timer) => clearTimeout(timer));
|
retryTimers.current.forEach((timer) => clearTimeout(timer));
|
||||||
retryTimers.current.clear();
|
retryTimers.current.clear();
|
||||||
|
subscribeState.current.clear();
|
||||||
};
|
};
|
||||||
}, [socket, entriesKey]);
|
}, [socket, entriesKey]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user