Files
GS13NG/tgui/packages/tgui-panel/ping/middleware.js
2021-03-04 21:51:20 +08:00

58 lines
1.5 KiB
JavaScript

/**
* @file
* @copyright 2020 Aleksej Komarov
* @license MIT
*/
import { sendMessage } from 'tgui/backend';
import { pingFail, pingSuccess } from './actions';
import { PING_INTERVAL, PING_QUEUE_SIZE, PING_TIMEOUT } from './constants';
export const pingMiddleware = store => {
let initialized = false;
let index = 0;
let interval;
const pings = [];
const sendPing = () => {
for (let i = 0; i < PING_QUEUE_SIZE; i++) {
const ping = pings[i];
if (ping && Date.now() - ping.sentAt > PING_TIMEOUT) {
pings[i] = null;
store.dispatch(pingFail());
}
}
const ping = { index, sentAt: Date.now() };
pings[index] = ping;
sendMessage({
type: 'ping',
payload: { index },
});
index = (index + 1) % PING_QUEUE_SIZE;
};
return next => action => {
const { type, payload } = action;
if (!initialized) {
initialized = true;
interval = setInterval(sendPing, PING_INTERVAL);
sendPing();
}
if (type === 'roundrestart') {
// Stop pinging because dreamseeker is currently reconnecting.
// Topic calls in the middle of reconnect will crash the connection.
clearInterval(interval);
return next(action);
}
if (type === 'pingReply') {
const { index } = payload;
const ping = pings[index];
// Received a timed out ping
if (!ping) {
return;
}
pings[index] = null;
return next(pingSuccess(ping));
}
return next(action);
};
};