From a8978034d2f8a6c8f4ff335e864aa29da754d3c2 Mon Sep 17 00:00:00 2001 From: Ismail Ali Date: Sat, 7 Jun 2025 14:25:42 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20=C3=84nderungen=20werden=20von=20websoc?= =?UTF-8?q?ket=20zu=20client=20gesendet=20und=20Redux=20aktualisiert=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/mainComponent/MapComponent.js | 13 ++- config/appVersion.js | 2 +- package-lock.json | 19 ++++ package.json | 3 +- server.js | 106 ++++++++++++++--------- 5 files changed, 91 insertions(+), 52 deletions(-) diff --git a/components/mainComponent/MapComponent.js b/components/mainComponent/MapComponent.js index cd731500b..a2873af08 100644 --- a/components/mainComponent/MapComponent.js +++ b/components/mainComponent/MapComponent.js @@ -801,21 +801,18 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const params = new URLSearchParams(window.location.search); const m = params.get("m"); const u = params.get("u"); + const mode = process.env.NEXT_PUBLIC_USE_MOCKS === "true" ? "mock" : "prod"; const socket = io({ - query: { - m, - u, - }, + query: { m, u, mode }, }); socket.on("connect", () => { - console.log("🔗 Socket verbunden", socket.id); + console.log("🔗 WebSocket verbunden (Modus:", mode, ")"); }); - socket.on("gisLinesStatusUpdated", newData => { - console.log("📡 Update erhalten für m/u:", m, u); - dispatch(fetchGisLinesStatusThunk(newData)); + socket.on("gisLinesStatusUpdated", data => { + dispatch(fetchGisLinesStatusThunk(data)); }); return () => { diff --git a/config/appVersion.js b/config/appVersion.js index 18de473bf..cf9cb0ac3 100644 --- a/config/appVersion.js +++ b/config/appVersion.js @@ -1,2 +1,2 @@ // /config/appVersion -export const APP_VERSION = "1.1.244"; +export const APP_VERSION = "1.1.245"; diff --git a/package-lock.json b/package-lock.json index 986933603..81ea324ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "xml2js": "^0.6.2" }, "devDependencies": { + "cross-env": "^7.0.3", "cypress": "^13.17.0", "husky": "^9.1.7", "identity-obj-proxy": "^3.0.0", @@ -2444,6 +2445,24 @@ "node": ">=10" } }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-fetch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", diff --git a/package.json b/package.json index 731745aaa..69fdfbe34 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "scripts": { "dev": "node server.js", "build": "next build", - "start": "NODE_ENV=production node server.js", + "start": "cross-env NODE_ENV=production node server.js", "export": "next export", "test": "jest", "cypress": "cypress open", @@ -46,6 +46,7 @@ "bump-version": "node ./scripts/bumpVersion.js" }, "devDependencies": { + "cross-env": "^7.0.3", "cypress": "^13.17.0", "husky": "^9.1.7", "identity-obj-proxy": "^3.0.0", diff --git a/server.js b/server.js index fbdbc92ab..52abd3c89 100644 --- a/server.js +++ b/server.js @@ -1,68 +1,90 @@ -// server.js -const express = require("express"); -const http = require("http"); +const { createServer } = require("http"); const next = require("next"); const { Server } = require("socket.io"); const fs = require("fs"); const path = require("path"); +const fetch = (...args) => import("node-fetch").then(({ default: fetch }) => fetch(...args)); -const port = parseInt(process.env.PORT, 10) || 3000; const dev = process.env.NODE_ENV !== "production"; const app = next({ dev }); const handle = app.getRequestHandler(); +const PORT = 3000; app.prepare().then(() => { - const expressApp = express(); - const server = http.createServer(expressApp); + const server = createServer((req, res) => { + handle(req, res); + }); + const io = new Server(server); - // Verbindung mit Clients io.on("connection", socket => { - console.log("✅ Client verbunden via socket.io"); + const { m, mode } = socket.handshake.query; + const idMap = m; + const isLiveMode = mode === "live" || mode === "prod"; - socket.on("message", data => { - console.log("💬 Nachricht vom Client:", data); - }); + let lastStatis = []; - socket.emit("message", { message: "Hallo vom socket.io Server" }); + const fetchData = async () => { + try { + let statis; - //--------- - const { m, u } = socket.handshake.query; + if (dev) { + const mockPath = path.join(process.cwd(), "mockData", "GisLinesStatus.json"); + const jsonStr = fs.readFileSync(mockPath, "utf-8"); + const json = JSON.parse(jsonStr); + statis = json?.Statis || []; + console.log("🧪 Mockdaten gelesen"); + } else { + const fetchUrl = `http://localhost/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`; + const res = await fetch(fetchUrl); + const text = await res.text(); - console.log(`🧩 WebSocket-Client verbunden mit Parametern: m=${m}, u=${u}`); + if (!text.startsWith("{")) { + console.error("❌ Webservice liefert kein valides JSON:", text.slice(0, 100)); + return; + } - // Du kannst diese Info verwenden, um gezielt nur bestimmte Daten zu senden: - socket.join(`map-${m}-user-${u}`); - }); + const json = JSON.parse(text); + statis = json?.Statis || []; + console.log("📡 Webservice-Daten empfangen"); + } - // 🌍 Next.js Routing - expressApp.all("*", (req, res) => { - return handle(req, res); - }); + const hasChanged = + statis.length !== lastStatis.length || + statis.some((entry, index) => { + const prev = lastStatis[index]; + return ( + !prev || + entry.Modul !== prev.Modul || + entry.ModulName !== prev.ModulName || + entry.Value !== prev.Value || + entry.Level !== prev.Level + ); + }); - // 📁 Datei überwachen: GisLinesStatus.json (Pfad anpassen falls nötig) - const statusFilePath = path.join(__dirname, "mockData", "GisLinesStatus.json"); - - fs.watchFile(statusFilePath, { interval: 5000 }, async () => { - console.log("📁 Änderung erkannt: GisLinesStatus.json"); - - try { - const content = fs.readFileSync(statusFilePath, "utf8"); - const data = JSON.parse(content); - - if (Array.isArray(data.Statis)) { - io.emit("gisLinesStatusUpdated", data.Statis); - console.log("📤 Update gesendet an Clients via Socket.IO"); - } else { - console.warn("⚠️ 'Statis' fehlt oder hat falsches Format"); + if (hasChanged) { + lastStatis = statis; + socket.emit("gisLinesStatusUpdated", statis); + console.log("✅ Änderung erkannt und gesendet"); + } else { + console.log("🔁 Keine Änderung festgestellt"); + } + } catch (error) { + console.error("❌ Fehler beim Datenabruf:", error.message); } - } catch (e) { - console.error("❌ Fehler beim Parsen von GisLinesStatus.json:", e.message); + }; + + if (isLiveMode) { + fetchData(); + const interval = setInterval(fetchData, 5000); + socket.on("disconnect", () => { + clearInterval(interval); + console.log("❌ WebSocket getrennt"); + }); } }); - // 🚀 Server starten - server.listen(port, () => { - console.log(`🚀 Server mit socket.io läuft auf http://localhost:${port}`); + server.listen(PORT, () => { + console.log(`🚀 App + Socket.io läuft auf http://localhost:${PORT}`); }); });