Files
segnapunti/server.js
Davide Grilli 1df239ed3d feat: salva partite su SQLite e aggiunge storico in dev
- Aggiunge src/db.js con better-sqlite3: tabella partite con nomi,
  modalità, set, formazione di partenza per set, punteggi e vincitore
- Salvataggio automatico al termine della partita (websocket-handler.js)
- Aggiunge formInizioSet in gameState per tracciare la formazione
  iniziale di ogni set
- Aggiunge storico.html: pagina vanilla dark-theme con lista partite
  espandibili (set, punteggio, formazioni)
- Aggiunge server storico su porta 3002 in dev (vite-plugin-websocket.js)
- Aggiunge endpoint /api/partite su displayApp (server.js)
- Migliora banner di avvio con URL storico locale e da rete
- Migliora log WebSocket: connessione aperta, ruolo unregistered, client rimanenti
- Aggiorna .gitignore: ignora tutta la cartella data/
2026-02-21 18:36:58 +01:00

99 lines
3.2 KiB
JavaScript

import { createServer } from 'http'
import express from 'express'
import { WebSocketServer } from 'ws'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
import { setupWebSocketHandler } from './src/websocket-handler.js'
import { printServerInfo } from './src/server-utils.js'
import { getPartite, getPartita } from './src/db.js'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
// --- Configurazione del server ---
const DISPLAY_PORT = process.env.PORT || 3000
const CONTROLLER_PORT = process.env.CONTROLLER_PORT || 3001
// ========================================
// Server Display (porta principale)
// ========================================
const displayApp = express()
// Espone i file generati dalla build di Vite.
displayApp.use(express.static(join(__dirname, 'dist')))
// API REST per le partite salvate.
displayApp.get('/api/partite', (_req, res) => {
try { res.json(getPartite()) }
catch (err) { res.status(500).json({ error: err.message }) }
})
displayApp.get('/api/partite/:id', (req, res) => {
try {
const p = getPartita(Number(req.params.id))
if (!p) return res.status(404).json({ error: 'Not found' })
res.json(p)
} catch (err) { res.status(500).json({ error: err.message }) }
})
// Fallback per SPA: restituisce `index.html` per tutte le route.
displayApp.get(/.*/, (_req, res) => {
res.sendFile(join(__dirname, 'dist', 'index.html'))
})
const displayServer = createServer(displayApp)
// Inizializza il server WebSocket condiviso.
const wss = new WebSocketServer({ noServer: true })
setupWebSocketHandler(wss)
displayServer.on('upgrade', (request, socket, head) => {
const pathname = new URL(request.url, `http://${request.headers.host}`).pathname
if (pathname === '/ws') {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request)
})
} else {
socket.destroy()
}
})
displayServer.listen(DISPLAY_PORT, '0.0.0.0', () => {
console.log(`[Display] Server running on port ${DISPLAY_PORT}`)
})
// ========================================
// Server Controller (porta separata)
// ========================================
const controllerApp = express()
// Espone gli stessi file statici della build.
// IMPORTANTE: { index: false } impedisce di servire index.html (il display) sulla root.
controllerApp.use(express.static(join(__dirname, 'dist'), { index: false }))
// Fallback: restituisce `controller.html` per tutte le route.
controllerApp.get(/.*/, (_req, res) => {
res.sendFile(join(__dirname, 'dist', 'controller.html'))
})
const controllerServer = createServer(controllerApp)
// Gestisce l'upgrade WebSocket anche sulla porta del controller.
controllerServer.on('upgrade', (request, socket, head) => {
const pathname = new URL(request.url, `http://${request.headers.host}`).pathname
if (pathname === '/ws') {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request)
})
} else {
socket.destroy()
}
})
controllerServer.listen(CONTROLLER_PORT, '0.0.0.0', () => {
printServerInfo(DISPLAY_PORT, CONTROLLER_PORT)
})