From 395975a111333ec31d404f1a70421f931c6cc914 Mon Sep 17 00:00:00 2001 From: Xargana Date: Sat, 3 May 2025 13:24:14 +0300 Subject: [PATCH] fixed stuff --- api/message-board/message-board.js | 98 +++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 10 deletions(-) diff --git a/api/message-board/message-board.js b/api/message-board/message-board.js index e8a19e7..553d4e2 100644 --- a/api/message-board/message-board.js +++ b/api/message-board/message-board.js @@ -1,7 +1,6 @@ const express = require("express"); const fs = require("fs"); const path = require("path"); - const router = express.Router(); // Path for persisting messages @@ -9,6 +8,10 @@ const MESSAGES_FILE_PATH = path.join(__dirname, 'messages-cache.json'); // In-memory storage with persistence let messages = []; +// Store active polling connections +let pendingConnections = []; +// Track the last message ID to help clients know what's new +let lastMessageId = 0; // Load existing messages from file if it exists function loadMessages() { @@ -17,6 +20,15 @@ function loadMessages() { const data = fs.readFileSync(MESSAGES_FILE_PATH, 'utf8'); messages = JSON.parse(data); console.log(`Loaded ${messages.length} messages from cache`); + + // Set the initial lastMessageId based on loaded messages + if (messages.length > 0) { + lastMessageId = messages.length; + // Add ID to each message if not present + messages.forEach((msg, index) => { + if (!msg.id) msg.id = index + 1; + }); + } } } catch (error) { console.error("Error loading messages from cache:", error); @@ -32,6 +44,28 @@ function saveMessages() { } } +// Notify all pending connections about new messages +function notifyNewMessages() { + const connectionsToNotify = [...pendingConnections]; + pendingConnections = []; + + connectionsToNotify.forEach(connection => { + const { res, lastId } = connection; + sendNewMessages(res, lastId); + }); +} + +// Send new messages to a client +function sendNewMessages(res, lastKnownId) { + const newMessages = messages.filter(msg => msg.id > lastKnownId); + const currentLastId = messages.length > 0 ? messages[messages.length - 1].id : lastKnownId; + + res.json({ + messages: newMessages, + lastId: currentLastId + }); +} + // Load messages at startup loadMessages(); @@ -44,11 +78,16 @@ router.post("/submit", express.json(), (req, res) => { return res.status(400).json({ error: "Missing name or message fields" }); } - messages.push({ - name, - message, - time: new Date().toISOString() - }); + lastMessageId++; + + const newMessage = { + id: lastMessageId, + name, + message, + time: new Date().toISOString() + }; + + messages.push(newMessage); // Keep only the latest 100 messages if (messages.length > 100) { @@ -58,6 +97,9 @@ router.post("/submit", express.json(), (req, res) => { // Save to file after update saveMessages(); + // Notify all waiting clients + notifyNewMessages(); + res.json({ success: true, message: "Message received" }); } catch (error) { console.error("Error handling message submission:", error); @@ -65,7 +107,7 @@ router.post("/submit", express.json(), (req, res) => { } }); -// Get messages as JSON +// Get all messages as JSON (keep for backward compatibility) router.get("/", (req, res) => { try { res.json({ messages }); @@ -75,6 +117,42 @@ router.get("/", (req, res) => { } }); +// Long polling endpoint for message updates +router.get("/poll", (req, res) => { + try { + const lastId = parseInt(req.query.lastId || "0", 10); + const newMessages = messages.filter(msg => msg.id > lastId); + + // If there are new messages, send them immediately + if (newMessages.length > 0) { + sendNewMessages(res, lastId); + } else { + // No new messages, set timeout to avoid hanging forever + const timeoutId = setTimeout(() => { + // Remove this connection from pending list + pendingConnections = pendingConnections.filter(conn => conn.res !== res); + sendNewMessages(res, lastId); + }, 30000); // 30 second timeout + + // Store the connection for later notification + pendingConnections.push({ + res, + lastId, + timeoutId + }); + + // Handle client disconnect + req.on('close', () => { + clearTimeout(timeoutId); + pendingConnections = pendingConnections.filter(conn => conn.res !== res); + }); + } + } catch (error) { + console.error("Error in long polling:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); + // Get messages as HTML router.get("/html", (req, res) => { try { @@ -94,8 +172,8 @@ router.get("/html", (req, res) => {

Public Message Pool

${messages.map(msg => `
- ${msg.name} - [${msg.time}]: + ${msg.name} + [${msg.time}]:
${msg.message}
`).join('')} @@ -111,4 +189,4 @@ router.get("/html", (req, res) => { } }); -module.exports = router; \ No newline at end of file +module.exports = router;