photo_server_json_flutter_c.../ws-server.js
2026-03-23 12:31:01 +01:00

128 lines
3.3 KiB
JavaScript

// ws-server.js
require("dotenv").config();
const WebSocket = require("ws");
const jwt = require("jsonwebtoken");
// -----------------------------------------------------
// CONFIGURAZIONE DA .env
// -----------------------------------------------------
const PORT = process.env.WS_PORT || 4002;
const HOST = process.env.WS_HOST || "0.0.0.0";
const JWT_SECRET = process.env.JWT_SECRET;
if (!JWT_SECRET) {
console.error("❌ ERRORE: JWT_SECRET non definito nel .env");
process.exit(1);
}
// -----------------------------------------------------
// AVVIO WEBSOCKET SERVER
// -----------------------------------------------------
const wss = new WebSocket.Server({
port: PORT,
host: HOST
});
console.log(`🚀 WebSocket server attivo su ws://${HOST}:${PORT}`);
// -----------------------------------------------------
// GESTIONE CONNESSIONI
// -----------------------------------------------------
wss.on("connection", (ws, req) => {
console.log("🔌 Nuovo client connesso");
ws.isAlive = true;
ws.on("pong", () => {
ws.isAlive = true;
});
ws.on("message", msg => {
let data;
try {
data = JSON.parse(msg);
} catch (err) {
console.error("❌ Errore parsing JSON:", err);
return;
}
// -----------------------------------------------------
// AUTENTICAZIONE JWT
// -----------------------------------------------------
if (data.type === "auth") {
try {
const payload = jwt.verify(data.token, JWT_SECRET);
ws.user = payload.name; // es: "Fabio"
ws.authenticated = true;
ws.send(JSON.stringify({
type: "auth_ok",
user: ws.user
}));
console.log(`🔐 Client autenticato: ${ws.user}`);
} catch (err) {
ws.send(JSON.stringify({
type: "auth_error",
error: err.message
}));
ws.close();
}
return;
}
// -----------------------------------------------------
// MESSAGGI NON AUTORIZZATI
// -----------------------------------------------------
if (!ws.authenticated) {
ws.send(JSON.stringify({
type: "error",
message: "Not authenticated"
}));
return;
}
// -----------------------------------------------------
// MESSAGGI DAL CLIENT (se vuoi gestirli)
// -----------------------------------------------------
console.log(`📨 Messaggio da ${ws.user}:`, data);
});
ws.on("close", () => {
console.log(`❌ Client disconnesso: ${ws.user || "sconosciuto"}`);
});
});
// -----------------------------------------------------
// HEARTBEAT (evita connessioni zombie)
// -----------------------------------------------------
setInterval(() => {
wss.clients.forEach(ws => {
if (!ws.isAlive) {
console.log(`💀 Connessione zombie terminata: ${ws.user}`);
return ws.terminate();
}
ws.isAlive = false;
ws.ping();
});
}, 30000);
// -----------------------------------------------------
// BROADCAST FILTRATO PER UTENTE
// -----------------------------------------------------
wss.broadcastToUser = function (user, msg) {
const json = JSON.stringify(msg);
for (const client of wss.clients) {
if (
client.readyState === WebSocket.OPEN &&
client.authenticated &&
client.user === user
) {
client.send(json);
}
}
};
module.exports = wss;