Auto-reconnect on server loss
This commit is contained in:
parent
450357db79
commit
2910789c86
112
client/src/ConnectionStatus.tsx
Normal file
112
client/src/ConnectionStatus.tsx
Normal file
@ -0,0 +1,112 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Typography,
|
||||
CircularProgress,
|
||||
Paper,
|
||||
LinearProgress
|
||||
} from '@mui/material';
|
||||
import { ReadyState } from 'react-use-websocket';
|
||||
|
||||
interface ConnectionStatusProps {
|
||||
readyState: ReadyState;
|
||||
reconnectAttempt?: number;
|
||||
}
|
||||
|
||||
const ConnectionStatus: React.FC<ConnectionStatusProps> = ({
|
||||
readyState,
|
||||
reconnectAttempt = 0
|
||||
}) => {
|
||||
const [countdown, setCountdown] = useState(0);
|
||||
|
||||
// Start countdown when connection is closed and we're attempting to reconnect
|
||||
useEffect(() => {
|
||||
if (readyState === ReadyState.CLOSED && reconnectAttempt > 0) {
|
||||
setCountdown(5);
|
||||
const interval = setInterval(() => {
|
||||
setCountdown(prev => {
|
||||
if (prev <= 1) {
|
||||
clearInterval(interval);
|
||||
return 0;
|
||||
}
|
||||
return prev - 1;
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [readyState, reconnectAttempt]);
|
||||
|
||||
const getConnectionStatusText = () => {
|
||||
switch (readyState) {
|
||||
case ReadyState.CONNECTING:
|
||||
return reconnectAttempt > 0 ? `Reconnecting... (attempt ${reconnectAttempt})` : 'Connecting to server...';
|
||||
case ReadyState.OPEN:
|
||||
return 'Connected';
|
||||
case ReadyState.CLOSING:
|
||||
return 'Disconnecting...';
|
||||
case ReadyState.CLOSED:
|
||||
if (reconnectAttempt > 0 && countdown > 0) {
|
||||
return `Connection lost. Retrying in ${countdown}s... (attempt ${reconnectAttempt})`;
|
||||
}
|
||||
return reconnectAttempt > 0 ? 'Reconnecting...' : 'Disconnected';
|
||||
case ReadyState.UNINSTANTIATED:
|
||||
return 'Initializing...';
|
||||
default:
|
||||
return 'Unknown connection state';
|
||||
}
|
||||
};
|
||||
|
||||
const getConnectionColor = () => {
|
||||
switch (readyState) {
|
||||
case ReadyState.OPEN:
|
||||
return 'success.main';
|
||||
case ReadyState.CONNECTING:
|
||||
return 'info.main';
|
||||
case ReadyState.CLOSED:
|
||||
return 'error.main';
|
||||
case ReadyState.CLOSING:
|
||||
return 'warning.main';
|
||||
default:
|
||||
return 'text.secondary';
|
||||
}
|
||||
};
|
||||
|
||||
const shouldShowProgress = readyState === ReadyState.CONNECTING ||
|
||||
(readyState === ReadyState.CLOSED && reconnectAttempt > 0);
|
||||
|
||||
return (
|
||||
<Paper
|
||||
sx={{
|
||||
p: 2,
|
||||
m: 2,
|
||||
width: 'fit-content',
|
||||
backgroundColor: readyState === ReadyState.CLOSED ? '#ffebee' : 'background.paper'
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
||||
{shouldShowProgress && (
|
||||
<CircularProgress size={20} />
|
||||
)}
|
||||
<Typography
|
||||
variant="h6"
|
||||
color={getConnectionColor()}
|
||||
>
|
||||
{getConnectionStatusText()}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{readyState === ReadyState.CLOSED && reconnectAttempt > 0 && countdown > 0 && (
|
||||
<Box sx={{ mt: 2, width: '100%' }}>
|
||||
<LinearProgress
|
||||
variant="determinate"
|
||||
value={((5 - countdown) / 5) * 100}
|
||||
sx={{ borderRadius: 1 }}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConnectionStatus;
|
44
client/src/WebRTCStatus.tsx
Normal file
44
client/src/WebRTCStatus.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { Box, CircularProgress, Typography } from '@mui/material';
|
||||
|
||||
interface WebRTCStatusProps {
|
||||
isNegotiating: boolean;
|
||||
connectionState?: string;
|
||||
}
|
||||
|
||||
const WebRTCStatus: React.FC<WebRTCStatusProps> = ({
|
||||
isNegotiating,
|
||||
connectionState
|
||||
}) => {
|
||||
if (!isNegotiating && connectionState !== 'connecting') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
className="webrtc-status"
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
||||
color: 'white',
|
||||
padding: 2,
|
||||
borderRadius: 2,
|
||||
zIndex: 10
|
||||
}}
|
||||
>
|
||||
<CircularProgress size={24} color="inherit" />
|
||||
<Typography variant="caption">
|
||||
{isNegotiating ? 'Negotiating WebRTC...' : 'Connecting...'}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default WebRTCStatus;
|
Loading…
x
Reference in New Issue
Block a user