feat: handle reconnection
This commit is contained in:
parent
16bba31786
commit
2bcb541c99
|
@ -142,6 +142,15 @@ const AugmentedParser = augmentParserWithThroughput(SocketIoParser);
|
||||||
const socket = createClient(window.location.href, {
|
const socket = createClient(window.location.href, {
|
||||||
parser: AugmentedParser,
|
parser: AugmentedParser,
|
||||||
});
|
});
|
||||||
|
let isConnected = false;
|
||||||
|
socket.on('connect', () => {
|
||||||
|
room.layers.destroy();
|
||||||
|
selfEntity = undefined;
|
||||||
|
isConnected = true;
|
||||||
|
});
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
isConnected = false;
|
||||||
|
});
|
||||||
// Mouse/touch movement.
|
// Mouse/touch movement.
|
||||||
const pointerMovementHandle = setInterval(() => {
|
const pointerMovementHandle = setInterval(() => {
|
||||||
do {
|
do {
|
||||||
|
@ -172,6 +181,9 @@ const pointerMovementHandle = setInterval(() => {
|
||||||
}, 1000 / 15);
|
}, 1000 / 15);
|
||||||
// Input messages.
|
// Input messages.
|
||||||
const inputHandle = setInterval(() => {
|
const inputHandle = setInterval(() => {
|
||||||
|
if (!isConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (actionState !== actionRegistry.state) {
|
if (actionState !== actionRegistry.state) {
|
||||||
actionState = actionRegistry.state;
|
actionState = actionRegistry.state;
|
||||||
socket.send(InputPacket.fromState(actionState));
|
socket.send(InputPacket.fromState(actionState));
|
||||||
|
@ -185,6 +197,9 @@ renderTicker.on('tick', () => {
|
||||||
});
|
});
|
||||||
let lastTime = performance.now();
|
let lastTime = performance.now();
|
||||||
const predictionHandle = setInterval(() => {
|
const predictionHandle = setInterval(() => {
|
||||||
|
if (!isConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const now = performance.now();
|
const now = performance.now();
|
||||||
const elapsed = (now - lastTime) / 1000;
|
const elapsed = (now - lastTime) / 1000;
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
|
@ -254,6 +269,9 @@ function applyStageLighting() {
|
||||||
}
|
}
|
||||||
// Render.
|
// Render.
|
||||||
function render() {
|
function render() {
|
||||||
|
if (!isConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
stage.tick();
|
stage.tick();
|
||||||
if (!mayRender) {
|
if (!mayRender) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -266,6 +284,7 @@ function render() {
|
||||||
const renderHandle = setAnimation(render);
|
const renderHandle = setAnimation(render);
|
||||||
// UI.
|
// UI.
|
||||||
const UiComponent = <Ui
|
const UiComponent = <Ui
|
||||||
|
socket={socket}
|
||||||
worldTime={worldTime}
|
worldTime={worldTime}
|
||||||
/>;
|
/>;
|
||||||
ReactDOM.render(UiComponent, stage.ui);
|
ReactDOM.render(UiComponent, stage.ui);
|
||||||
|
|
78
client/ui/connection-status.js
Normal file
78
client/ui/connection-status.js
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// 3rd party.
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import React, {useEffect, useState} from 'react';
|
||||||
|
// 2nd party.
|
||||||
|
import {compose} from '@avocado/core';
|
||||||
|
import contempo from 'contempo';
|
||||||
|
|
||||||
|
const decorate = compose(
|
||||||
|
contempo(`
|
||||||
|
.connection-status {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.connection-status.interrupted {
|
||||||
|
background-color: rgba(0, 0, 0, .75);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.connection-status.interrupted .message {
|
||||||
|
color: white;
|
||||||
|
font-family: mono;
|
||||||
|
font-size: 0.7em;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.connection-status.interrupted .message .dots {
|
||||||
|
color: rgb(150, 150, 150);
|
||||||
|
font-size: 0.5em;
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
);
|
||||||
|
|
||||||
|
const ConnectionStatusComponent = ({socket}) => {
|
||||||
|
// Start true even if not really connected to prevent initial "interrupted"
|
||||||
|
// state.
|
||||||
|
const [isConnected, setIsConnected] = useState(true);
|
||||||
|
const [dots, setDots] = useState(0);
|
||||||
|
// Juggle connected state.
|
||||||
|
useEffect(() => {
|
||||||
|
const onConnect = () => {
|
||||||
|
setIsConnected(true);
|
||||||
|
};
|
||||||
|
socket.on('connect', onConnect);
|
||||||
|
const onDisconnect = () => {
|
||||||
|
setIsConnected(false);
|
||||||
|
};
|
||||||
|
socket.on('disconnect', onDisconnect);
|
||||||
|
return () => {
|
||||||
|
socket.off('connect', onConnect);
|
||||||
|
socket.off('disconnect', onDisconnect);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
// Make the dots dance.
|
||||||
|
useEffect(() => {
|
||||||
|
if (isConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
setDots((dots + 1) % 39);
|
||||||
|
}, 50);
|
||||||
|
}, [dots, isConnected]);
|
||||||
|
const renderedDots = Array(dots + 1).fill('.').join('');
|
||||||
|
return <div className={classnames(
|
||||||
|
'connection-status',
|
||||||
|
!isConnected ? 'interrupted' : '',
|
||||||
|
'unselectable',
|
||||||
|
)}>
|
||||||
|
<div className="message">
|
||||||
|
<p>:[ Connection interrupted ]:</p>
|
||||||
|
<p className="dots">{renderedDots}</p>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default decorate(ConnectionStatusComponent);
|
|
@ -2,11 +2,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {hot} from 'react-hot-loader/root';
|
import {hot} from 'react-hot-loader/root';
|
||||||
// 1st party.
|
// 1st party.
|
||||||
|
import ConnectionStatus from './connection-status';
|
||||||
import WorldTime from './world-time';
|
import WorldTime from './world-time';
|
||||||
|
|
||||||
const Ui = ({worldTime}) => {
|
const Ui = ({socket, worldTime}) => {
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<WorldTime worldTime={worldTime} />
|
<WorldTime worldTime={worldTime} />
|
||||||
|
<ConnectionStatus socket={socket} />
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user