Der Socket.IO-Server lief als zweiter Server auf Port 3001 und brauchte
deswegen cors: { origin: "*" }; die Clients bauten ihre Verbindungs-URL aus
window.location.hostname und dem festen Port zusammen.
Er wird jetzt ohne eigenen Port erzeugt und in bin/www per io.attach() an den
bestehenden HTTP-Server gehaengt. Erzeugen und Anhaengen sind getrennt, weil das
Modul beim Laden der Routen ausgewertet wird, also bevor der HTTP-Server
existiert. Die Clients rufen nur noch io() ohne Argument auf und verbinden sich
damit zur Herkunft der Seite zurueck.
Damit entfallen der zweite Port, die CORS-Ausnahme und eine moegliche zweite
Firewall-Regel auf dem Pi. Verifiziert: Port 3001 lauscht nicht mehr, alle
Events (score, timerDurationLeft, timerEnded, scoreSideswitch, refresh) kommen
ueber Port 3000 an, Reconnect funktioniert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
68 lines
No EOL
3.2 KiB
JavaScript
68 lines
No EOL
3.2 KiB
JavaScript
// Socket.IO laeuft am selben Host und Port wie die Seite, io() ohne Argument
|
|
// verbindet sich dorthin zurueck.
|
|
const socket = io();
|
|
|
|
// ######################################################################################################################################################
|
|
// Websockets event handler
|
|
// ######################################################################################################################################################
|
|
|
|
// 'connect' feuert bei jeder Verbindung, auch nach einem Reconnect. Da der Pi das WLAN
|
|
// selbst aufspannt, sind kurze Abbrueche normal: danach werden Timer und Spielstand neu
|
|
// geholt, damit die Anzeige nicht auf einem veralteten Stand haengen bleibt.
|
|
socket.on('connect', () => {
|
|
console.log("Verbunden");
|
|
initialUpdate();
|
|
});
|
|
|
|
socket.on('timerDurationLeft', (message) => {
|
|
console.log(message) // Log durationLeft in client console
|
|
document.getElementById("durationLeft").innerHTML = message; // Display durationLeft in corresponding html Element
|
|
});
|
|
|
|
socket.on('timerEnded', (message) => {
|
|
document.getElementById("durationLeft").innerHTML = "ENDE"; // Display "STOP" in same html element as the duration
|
|
});
|
|
|
|
socket.on('refresh', (message) => {
|
|
document.location.reload() // Reload page on received 'refresh' messagen
|
|
});
|
|
|
|
// ######################################################################################################################################################
|
|
// General functions
|
|
// ######################################################################################################################################################
|
|
|
|
// Holt JSON von einem Endpunkt. Liefert null statt zu werfen, wenn der Server nicht
|
|
// erreichbar ist oder mit einem Fehler antwortet.
|
|
async function fetchJson(url) {
|
|
try {
|
|
const response = await fetch(url);
|
|
if(!response.ok) {
|
|
console.error("Anfrage fehlgeschlagen:", url, response.status);
|
|
return null;
|
|
}
|
|
return await response.json();
|
|
} catch (err) {
|
|
console.error("Server nicht erreichbar:", url, err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Update DOM timer elements from passed values
|
|
function updateTimerFrontend(values) {
|
|
document.getElementById("durationLeft").innerHTML = values.print; // Display durationLeft as prettyfied string
|
|
}
|
|
|
|
// Initial update gets called whenever page has been loaded
|
|
async function initialUpdate() {
|
|
timerGetValues(); // Request new values for timer
|
|
}
|
|
|
|
// ######################################################################################################################################################
|
|
// Timerfunctions
|
|
// ######################################################################################################################################################
|
|
|
|
// Request important timer values
|
|
async function timerGetValues() {
|
|
const data = await fetchJson("/admin/timerGetValues"); // Call API Endpoint /admin/timerGetValues
|
|
if(data) updateTimerFrontend(data); // Update admin frontend
|
|
} |