fix: prevent unnecessary RPC calls for pending sessions and increase rate limit

Changes:
- Add permission checks before making getVideoState, getKeyboardLedState,
  and getKeyDownState RPC calls to prevent rejected requests for sessions
  without VIDEO_VIEW permission
- Fix infinite loop issue by excluding hasPermission from useEffect
  dependency arrays (functions recreated on render cause infinite loops)
- Increase RPC rate limit from 100 to 500 per second to support 10+
  concurrent sessions with broadcasts and state updates

This eliminates console spam from permission denied errors and log spam
from continuous RPC calls, while improving multi-session performance.
This commit is contained in:
Alex P 2025-10-10 22:10:33 +03:00
parent 821675cd21
commit f90c255656
2 changed files with 7 additions and 1 deletions

View File

@ -807,11 +807,13 @@ export default function KvmIdRoute() {
useEffect(() => {
if (rpcDataChannel?.readyState !== "open") return;
if (!hasPermission(Permission.VIDEO_VIEW)) return;
send("getVideoState", {}, (resp: JsonRpcResponse) => {
if ("error" in resp) return;
const hdmiState = resp.result as Parameters<VideoState["setHdmiState"]>[0];
setHdmiState(hdmiState);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rpcDataChannel?.readyState, send, setHdmiState]);
const [needLedState, setNeedLedState] = useState(true);
@ -820,6 +822,7 @@ export default function KvmIdRoute() {
useEffect(() => {
if (rpcDataChannel?.readyState !== "open") return;
if (!needLedState) return;
if (!hasPermission(Permission.VIDEO_VIEW)) return;
send("getKeyboardLedState", {}, (resp: JsonRpcResponse) => {
if ("error" in resp) {
@ -831,6 +834,7 @@ export default function KvmIdRoute() {
}
setNeedLedState(false);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rpcDataChannel?.readyState, send, setKeyboardLedState, keyboardLedState, needLedState]);
const [needKeyDownState, setNeedKeyDownState] = useState(true);
@ -839,6 +843,7 @@ export default function KvmIdRoute() {
useEffect(() => {
if (rpcDataChannel?.readyState !== "open") return;
if (!needKeyDownState) return;
if (!hasPermission(Permission.VIDEO_VIEW)) return;
send("getKeyDownState", {}, (resp: JsonRpcResponse) => {
if ("error" in resp) {
@ -856,6 +861,7 @@ export default function KvmIdRoute() {
}
setNeedKeyDownState(false);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [keysDownState, needKeyDownState, rpcDataChannel?.readyState, send, setKeysDownState, setHidRpcDisabled]);
// When the update is successful, we need to refresh the client javascript and show a success modal

View File

@ -88,7 +88,7 @@ func getActiveSessions() int {
// CheckRPCRateLimit checks if the session has exceeded RPC rate limits (DoS protection)
func (s *Session) CheckRPCRateLimit() bool {
const (
maxRPCPerSecond = 100 // Increased from 20 to accommodate multi-session polling and reconnections
maxRPCPerSecond = 500 // Increased to support 10+ concurrent sessions with broadcasts and state updates
rateLimitWindow = time.Second
)