mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
chat history, better turn queue updates
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
||||
<title>Multi Roomba Rover</title>
|
||||
<script type="module" crossorigin src="/assets/index-CvfJ6hKE.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-UA5S-yPp.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BY_dmM98.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -3,6 +3,9 @@ const { httpServer } = require('./http');
|
||||
|
||||
const io = new SocketIOServer(httpServer, {
|
||||
cors: { origin: '*' },
|
||||
transports: ['websocket', 'polling'],
|
||||
pingInterval: 5000,
|
||||
pingTimeout: 7000,
|
||||
});
|
||||
|
||||
// Allow more service listeners without warnings.
|
||||
|
||||
@@ -9,8 +9,6 @@ httpServer.on('upgrade', (req, socket, head) => {
|
||||
roverWSS.handleUpgrade(req, socket, head, (ws) => {
|
||||
roverWSS.emit('connection', ws, req);
|
||||
});
|
||||
} else {
|
||||
socket.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ const RATE_LIMIT_WINDOW_MS = 8000;
|
||||
const RATE_LIMIT_MAX = 5;
|
||||
const rateBuckets = new Map(); // socketId -> [timestamps]
|
||||
|
||||
const MAX_HISTORY = 100;
|
||||
const history = [];
|
||||
|
||||
const PROFANITY_LIST = ['bitch', 'cunt', 'nigger', 'nigga', 'asshole', 'dick'];
|
||||
const DUPLICATE_WINDOW_MS = 15000;
|
||||
const lastMessageBySocket = new Map(); // socketId -> { text, ts }
|
||||
@@ -83,7 +86,15 @@ function buildMessage(socket, text, meta = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function pushHistory(message) {
|
||||
history.push(message);
|
||||
if (history.length > MAX_HISTORY) {
|
||||
history.shift();
|
||||
}
|
||||
}
|
||||
|
||||
function broadcastMessage(message) {
|
||||
pushHistory(message);
|
||||
publishEvent({ source: 'chat', type: 'chat:message', payload: message });
|
||||
}
|
||||
|
||||
@@ -208,6 +219,7 @@ function sendExternalMessage({
|
||||
}
|
||||
|
||||
io.on('connection', (socket) => {
|
||||
socket.emit('chat:init', history);
|
||||
socket.on('chat:send', (payload = {}, cb = () => {}) => handleIncoming(payload, socket, cb));
|
||||
});
|
||||
|
||||
|
||||
@@ -657,6 +657,10 @@ io.on('connection', (socket) => {
|
||||
socket.on('subscribeAll', handleSubscribeAll);
|
||||
socket.on('session:subscribeAll', handleSubscribeAll);
|
||||
|
||||
socket.on('disconnecting', () => {
|
||||
logger.info('Socket disconnecting', socket.id);
|
||||
removeSocket(socket);
|
||||
});
|
||||
socket.on('disconnect', () => {
|
||||
logger.info('Socket disconnected', socket.id);
|
||||
removeSocket(socket);
|
||||
|
||||
@@ -9,6 +9,7 @@ const activeDrivers = new Map();
|
||||
const TURN_DURATION_MS = 60 * 1000;
|
||||
const IDLE_TIMEOUT_MS = 7 * 1000;
|
||||
const MAX_IDLE_SKIPS = 3;
|
||||
const STALE_REAPER_MS = 5000;
|
||||
const turnEvents = new EventEmitter();
|
||||
const turnDeadlines = new Map(); // roverId -> timestamp when current driver expires
|
||||
const idleDeadlines = new Map(); // roverId -> timestamp when idle skip will happen
|
||||
@@ -268,16 +269,44 @@ function removeDriverCompletely(roverId, socketId) {
|
||||
function recordActivity(roverId, socketId) {
|
||||
const queue = driverQueues.get(roverId);
|
||||
if (!queue || queue.current !== socketId) return;
|
||||
if (idleDisarmed.get(roverId)) return;
|
||||
idleDisarmed.set(roverId, true);
|
||||
const hadDeadline = idleDeadlines.has(roverId);
|
||||
clearTimeout(idleTimers.get(roverId));
|
||||
idleDeadlines.delete(roverId);
|
||||
turnEvents.emit('queue', { roverId, reason: 'activity' });
|
||||
if (hadDeadline) {
|
||||
turnEvents.emit('queue', { roverId, reason: 'activity' });
|
||||
}
|
||||
}
|
||||
|
||||
modeEvents.on('change', (mode) => {
|
||||
driverQueues.forEach((_, roverId) => syncState(roverId));
|
||||
});
|
||||
|
||||
function reapStaleDrivers() {
|
||||
const staleIds = new Set();
|
||||
driverQueues.forEach((queue) => {
|
||||
queue.queue.forEach((socketId) => {
|
||||
if (!io.sockets.sockets.has(socketId)) {
|
||||
staleIds.add(socketId);
|
||||
}
|
||||
});
|
||||
if (queue.current && !io.sockets.sockets.has(queue.current)) {
|
||||
staleIds.add(queue.current);
|
||||
}
|
||||
});
|
||||
if (staleIds.size === 0) return;
|
||||
driverQueues.forEach((queue, roverId) => {
|
||||
staleIds.forEach((socketId) => {
|
||||
if (queue.current === socketId || queue.queue.includes(socketId)) {
|
||||
driverRemoved(roverId, socketId);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(reapStaleDrivers, STALE_REAPER_MS);
|
||||
|
||||
module.exports = {
|
||||
driverAdded,
|
||||
driverRemoved,
|
||||
|
||||
Reference in New Issue
Block a user