Finish server restructuring
This commit is contained in:
parent
f4258fb35f
commit
136c51ba46
3 changed files with 91 additions and 83 deletions
|
@ -50,66 +50,66 @@ router.post('/createPartyLine', [
|
|||
|
||||
// Route to delete a party line
|
||||
router.delete('/deletePartyLine', [
|
||||
body('partyLine').isString().trim().escape().notEmpty().withMessage('Invalid party line name')
|
||||
], (req: any, res: any) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({ errors: errors.array() });
|
||||
body('partyLine').isString().trim().escape().notEmpty().withMessage('Invalid party line name')
|
||||
], (req: any, res: any) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({ errors: errors.array() });
|
||||
}
|
||||
try {
|
||||
const { partyLine: currentPartyLine } = req.body;
|
||||
const partyLine = partyLines[currentPartyLine];
|
||||
if (!partyLine) {
|
||||
return res.status(404).send({ status: 'Party line not found' });
|
||||
}
|
||||
try {
|
||||
const { partyLine: currentPartyLine } = req.body;
|
||||
const partyLine = partyLines[currentPartyLine];
|
||||
if (!partyLine) {
|
||||
return res.status(404).send({ status: 'Party line not found' });
|
||||
}
|
||||
|
||||
// Broadcast deletion message to all clients
|
||||
broadcast(currentPartyLine, 'PARTY_LINE_DELETED');
|
||||
|
||||
// Disconnect all clients
|
||||
partyLine.clients.forEach((client: any) => {
|
||||
console.log(`DISCONNECTING: { partyLine: ${currentPartyLine}, clientId: ${client.clientId} }`);
|
||||
client.response.end();
|
||||
});
|
||||
|
||||
// Delete the party line
|
||||
delete partyLines[currentPartyLine];
|
||||
console.log(`DELETE: { partyLine: ${currentPartyLine} }`);
|
||||
res.status(200).send({ status: 'Party line deleted', currentPartyLine });
|
||||
} catch (error) {
|
||||
console.error('ERROR: Failed to delete party line', error);
|
||||
res.status(500).send({ status: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
// Route to send an event to a party line
|
||||
// Broadcast deletion message to all clients
|
||||
broadcast(currentPartyLine, 'PARTY_LINE_DELETED');
|
||||
|
||||
// Disconnect all clients
|
||||
partyLine.clients.forEach((client: any) => {
|
||||
console.log(`DISCONNECTING: { partyLine: ${currentPartyLine}, clientId: ${client.clientId} }`);
|
||||
client.response.end();
|
||||
});
|
||||
|
||||
// Delete the party line
|
||||
delete partyLines[currentPartyLine];
|
||||
console.log(`DELETE: { partyLine: ${currentPartyLine} }`);
|
||||
res.status(200).send({ status: 'Party line deleted', currentPartyLine });
|
||||
} catch (error) {
|
||||
console.error('ERROR: Failed to delete party line', error);
|
||||
res.status(500).send({ status: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
// Route to send an event to a party line
|
||||
router.post('/rumor', [
|
||||
body('partyLine').isString().trim().escape().notEmpty().withMessage('Invalid party line name'),
|
||||
body('rumor').isString().trim().escape().notEmpty().withMessage('Invalid rumor')
|
||||
], (req: any, res: any) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({ errors: errors.array() });
|
||||
body('partyLine').isString().trim().escape().notEmpty().withMessage('Invalid party line name'),
|
||||
body('rumor').isString().trim().escape().notEmpty().withMessage('Invalid rumor')
|
||||
], (req: any, res: any) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(400).json({ errors: errors.array() });
|
||||
}
|
||||
try {
|
||||
const { partyLine: connectedPartyLine, rumor } = req.body;
|
||||
const partyLine = partyLines[connectedPartyLine];
|
||||
if (!partyLine) {
|
||||
return res.status(404).send({ status: 'Party line not found' });
|
||||
}
|
||||
try {
|
||||
const { partyLine: connectedPartyLine, rumor } = req.body;
|
||||
const partyLine = partyLines[connectedPartyLine];
|
||||
if (!partyLine) {
|
||||
return res.status(404).send({ status: 'Party line not found' });
|
||||
}
|
||||
|
||||
console.log(`RECEIVE: { partyLine: ${connectedPartyLine}, rumor: ${rumor} }`);
|
||||
|
||||
// Update the last event and broadcast it to all clients
|
||||
partyLine.lastEvent = rumor;
|
||||
partyLine.clients.forEach((client: any) => {
|
||||
client.response.write(`data: ${rumor}\n\n`);
|
||||
});
|
||||
res.status(200).send({ status: 'Rumor broadcast' });
|
||||
} catch (error) {
|
||||
console.error('ERROR: Failed to send event', error);
|
||||
res.status(500).send({ status: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
console.log(`RECEIVE: { partyLine: ${connectedPartyLine}, rumor: ${rumor} }`);
|
||||
|
||||
// Update the last event and broadcast it to all clients
|
||||
partyLine.lastEvent = rumor;
|
||||
partyLine.clients.forEach((client: any) => {
|
||||
client.response.write(`data: ${rumor}\n\n`);
|
||||
});
|
||||
res.status(200).send({ status: 'Rumor broadcast' });
|
||||
} catch (error) {
|
||||
console.error('ERROR: Failed to send event', error);
|
||||
res.status(500).send({ status: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -4,12 +4,11 @@ import cors from 'cors';
|
|||
import bodyParser from 'body-parser';
|
||||
import helmet from 'helmet';
|
||||
import path from 'path';
|
||||
import { partyLines } from './stores/dataStore';
|
||||
import { ENVIRONMENT, PORT, CLIENT_URL, DOCKER } from './stores/configStore';
|
||||
import { broadcast } from './services/broadcastService';
|
||||
import connectionRoutes from './routes/connectionRoutes';
|
||||
import managementRoutes from './routes/managementRoutes';
|
||||
import navigationRoutes from './routes/navigationRoutes';
|
||||
import { maintenanceService } from "./services/maintenanceService";
|
||||
|
||||
const app = express();
|
||||
|
||||
|
@ -35,6 +34,8 @@ app.use(cors(corsOptions));
|
|||
app.use(bodyParser.json());
|
||||
app.use(helmet());
|
||||
app.use(limiter);
|
||||
|
||||
// Serve the client's static files
|
||||
app.use('/', express.static(path.join(__dirname, '../static')));
|
||||
|
||||
// Force HTTPS redirection and CSP in production
|
||||
|
@ -47,21 +48,21 @@ if (ENVIRONMENT === 'production') {
|
|||
});
|
||||
|
||||
app.use(
|
||||
helmet.contentSecurityPolicy({
|
||||
useDefaults: true,
|
||||
directives: {
|
||||
'script-src': ['\'self\''],
|
||||
'img-src': ['\'self\'', 'data:'],
|
||||
'connect-src': ['\'self\'']
|
||||
}
|
||||
})
|
||||
helmet.contentSecurityPolicy({
|
||||
useDefaults: true,
|
||||
directives: {
|
||||
'script-src': ['\'self\''],
|
||||
'img-src': ['\'self\'', 'data:'],
|
||||
'connect-src': ['\'self\'']
|
||||
}
|
||||
})
|
||||
);
|
||||
} else {
|
||||
// Disable CSP for non-prod
|
||||
app.use(
|
||||
helmet({
|
||||
contentSecurityPolicy: false,
|
||||
}),
|
||||
helmet({
|
||||
contentSecurityPolicy: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -70,19 +71,10 @@ app.use(navigationRoutes);
|
|||
app.use(managementRoutes);
|
||||
app.use(connectionRoutes);
|
||||
|
||||
// Periodically resend the last rumor and clean up inactive party lines
|
||||
// Periodically run the maintenance service
|
||||
// Which is: Resend the last rumor and clean up inactive party lines
|
||||
setInterval(() => {
|
||||
const now = Date.now();
|
||||
Object.keys(partyLines).forEach((currentPartyLine) => {
|
||||
const partyLine = partyLines[currentPartyLine];
|
||||
if (partyLine.lastEvent && partyLine.clients.length > 0) {
|
||||
broadcast(currentPartyLine, partyLine.lastEvent);
|
||||
}
|
||||
if (now - partyLine.lastActivity > 3600000) { // 1 hour in milliseconds
|
||||
console.log(`DELETE: Deleting inactive party line ${currentPartyLine}`);
|
||||
delete partyLines[currentPartyLine];
|
||||
}
|
||||
});
|
||||
maintenanceService();
|
||||
}, 30000);
|
||||
|
||||
// Start the server
|
||||
|
|
16
server/src/services/maintenanceService.ts
Normal file
16
server/src/services/maintenanceService.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { partyLines } from "../stores/dataStore";
|
||||
import { broadcast } from "./broadcastService";
|
||||
|
||||
export const maintenanceService = () => {
|
||||
const now = Date.now();
|
||||
Object.keys(partyLines).forEach((currentPartyLine) => {
|
||||
const partyLine = partyLines[currentPartyLine];
|
||||
if (partyLine.lastEvent && partyLine.clients.length > 0) {
|
||||
broadcast(currentPartyLine, partyLine.lastEvent);
|
||||
}
|
||||
if (now - partyLine.lastActivity > 3600000) { // 1 hour in milliseconds
|
||||
console.log(`DELETE: Deleting inactive party line ${currentPartyLine}`);
|
||||
delete partyLines[currentPartyLine];
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Add table
Reference in a new issue