fix(striker-ui): attempt reconnect after unclean disconnect in VNC

main
Tsu-ba-me 2 years ago
parent c4fd8cc2f6
commit 8d343e5cca
  1. 64
      striker-ui/components/Display/FullSize.tsx
  2. 6
      striker-ui/components/Display/VncDisplay.tsx

@ -12,7 +12,7 @@ import {
Typography, Typography,
} from '@mui/material'; } from '@mui/material';
import RFB from '@novnc/novnc/core/rfb'; import RFB from '@novnc/novnc/core/rfb';
import { useState, useRef, useEffect, FC } from 'react'; import { useState, useRef, useEffect, FC, useCallback } from 'react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import API_BASE_URL from '../../lib/consts/API_BASE_URL'; import API_BASE_URL from '../../lib/consts/API_BASE_URL';
@ -131,42 +131,44 @@ const FullSize: FC<FullSizeProps> = ({
const [vncConnecting, setVncConnecting] = useProtectedState<boolean>(false); const [vncConnecting, setVncConnecting] = useProtectedState<boolean>(false);
const [isError, setIsError] = useProtectedState<boolean>(false); const [isError, setIsError] = useProtectedState<boolean>(false);
useEffect(() => { const connectVnc = useCallback(async () => {
if (typeof window !== 'undefined') { if (vncConnection || vncConnecting) return;
hostname.current = window.location.hostname;
}
if (!vncConnection && !vncConnecting) setVncConnecting(true);
(async () => {
setVncConnecting(true);
try { try {
const res = await putFetchWithTimeout( const res = await putFetchWithTimeout(
CMD_VNC_PIPE_URL, CMD_VNC_PIPE_URL,
{ {
serverUuid: serverUUID, serverUuid: serverUUID,
open: true, open: true,
}, },
120000, 120000,
); );
setVncConnection(await res.json()); setVncConnection(await res.json());
} catch { } catch {
setIsError(true); setIsError(true);
} finally { } finally {
setVncConnecting(false); setVncConnecting(false);
} }
})();
}, [ }, [
serverUUID, serverUUID,
vncConnection,
isError,
setVncConnection,
setIsError, setIsError,
vncConnecting,
setVncConnecting, setVncConnecting,
setVncConnection,
vncConnecting,
vncConnection,
]); ]);
useEffect(() => {
if (typeof window !== 'undefined') {
hostname.current = window.location.hostname;
}
connectVnc();
}, [connectVnc]);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>): void => { const handleClick = (event: React.MouseEvent<HTMLButtonElement>): void => {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
}; };
@ -214,6 +216,12 @@ const FullSize: FC<FullSizeProps> = ({
background="" background=""
qualityLevel={6} qualityLevel={6}
compressionLevel={2} compressionLevel={2}
onDisconnect={({ detail: { clean } }) => {
if (!clean) {
setVncConnection(undefined);
connectVnc();
}
}}
/> />
<Box> <Box>
<Box className={classes.closeBox}> <Box className={classes.closeBox}>

@ -14,6 +14,7 @@ type Props = {
background: string; background: string;
qualityLevel: number; qualityLevel: number;
compressionLevel: number; compressionLevel: number;
onDisconnect: (event: { detail: { clean: boolean } }) => void;
}; };
const VncDisplay = (props: Props): JSX.Element => { const VncDisplay = (props: Props): JSX.Element => {
@ -32,6 +33,7 @@ const VncDisplay = (props: Props): JSX.Element => {
background, background,
qualityLevel, qualityLevel,
compressionLevel, compressionLevel,
onDisconnect,
} = props; } = props;
useEffect(() => { useEffect(() => {
@ -59,6 +61,10 @@ const VncDisplay = (props: Props): JSX.Element => {
rfb.current.background = background; rfb.current.background = background;
rfb.current.qualityLevel = qualityLevel; rfb.current.qualityLevel = qualityLevel;
rfb.current.compressionLevel = compressionLevel; rfb.current.compressionLevel = compressionLevel;
// RFB extends custom class EventTargetMixin;
// the usual .on or .once doesn't exist.
rfb.current.addEventListener('disconnect', onDisconnect);
} }
/* eslint-disable consistent-return */ /* eslint-disable consistent-return */

Loading…
Cancel
Save