diff --git a/Apps/backend/src/main.js b/Apps/backend/src/main.js index cfe758d9..6e7b594c 100644 --- a/Apps/backend/src/main.js +++ b/Apps/backend/src/main.js @@ -1,5 +1,5 @@ import dgram from "node:dgram"; -import WebSocket, {WebSocketServer} from 'ws'; +import { WebSocketServer } from 'ws'; const server = dgram.createSocket("udp4"); const socket = new WebSocketServer({ @@ -8,11 +8,21 @@ const socket = new WebSocketServer({ }, () => { console.log("WebSocket Server started on 0.0.0.0:9000") }); +/** Frontend client (WebSocket Connection) */ let client = undefined; +/** Received packages from generator */ +let packageCounter = 0 +/** Sent packages to frontend */ +let packageCounterWS = 0 + +let chunkCounter = 0 +/** Array which will be send to frontend */ +let sendArray = [] socket.on('connection', (clientSocket) => { client = clientSocket client.send("connection established") + console.log(`Connection established remote=`) }); server.on("error", (err) => { @@ -20,17 +30,21 @@ server.on("error", (err) => { server.close(package_recieved); }); +/** + * Receive incoming UDP packages and handle them + * @param {Float64Array} msg.bufffer + */ server.on("message", (msg, rinfo) => { let samples = new Float64Array(msg.buffer); + packageCounter += 1 - if (client !== undefined && client !== null) { - client.send(samples) - } + handle(samples, 200) }); server.on("listening", () => { const address = server.address(); console.log(`Server listening on ${address.address}:${address.port}`); + setupPpsCalculator() }); server.bind( @@ -38,7 +52,53 @@ server.bind( process.env.HOST_ADDRESS || "0.0.0.0" ); -socket.onopen = function(e) { - alert("[open] Connection established"); - alert("Sending to server"); -}; \ No newline at end of file +/** + * Set the interval for tracking the received PPS + */ +function setupPpsCalculator() { + setInterval(function () { calculatePackagesPerSecond() }, 1000); +} + +socket.onopen = function (e) { + console.log("[open] Connection established"); + console.log("Sending to server"); +}; + +/** + * Calculates the packages per second received on the UDP socket + */ +function calculatePackagesPerSecond() { + console.log("Current rcv PPS: " + packageCounter + " | Current sending PPS: " + packageCounterWS) + packageCounter = 0; + packageCounterWS = 0; +} + +/** + * Handle incoming UDP datagrams. + * + * 1000 packages * 10 channel * 64 bit/value = 79 kB + * PPS of 10 = 790 kB/s network traffic towards frontend + * + * UDP datagrams are packaged to a size of and sent to the connected clients on the web socket + * We use a normal JS array as temporary buffer to support push operations and a Float64Buffer for sending + * @param {Float64Array} data + * @param {number} maxNumberOfChunks + */ +function handle(data, maxNumberOfChunks) { + if (chunkCounter === maxNumberOfChunks) { + packageCounterWS += 1 + + let pkg = new Float64Array(sendArray) + + if (client !== undefined && client !== null) { + client.send(pkg) + } + // Reset chunk stats + sendArray = [] + chunkCounter = 0 + } + else { + sendArray.push(...data) + chunkCounter += 1 + } +} \ No newline at end of file diff --git a/Apps/docker-compose.yml b/Apps/docker-compose.yml index 955a3790..e9d863b4 100644 --- a/Apps/docker-compose.yml +++ b/Apps/docker-compose.yml @@ -11,7 +11,7 @@ services: environment: - HOST=0.0.0.0:34254 - TARGET=backend:34255 - - PPS=100.0 + - PPS=100000.0 - SIG_FREQ=1.0 ports: - 34254:34254 @@ -31,7 +31,6 @@ services: restart: unless-stopped ports: - 5000:80 - - 9001:9000 networks: - internal - web diff --git a/Apps/frontend/Dockerfile b/Apps/frontend/Dockerfile index 72c42828..5d19a0d3 100644 --- a/Apps/frontend/Dockerfile +++ b/Apps/frontend/Dockerfile @@ -16,7 +16,7 @@ RUN npm install COPY . ./ # Expose vite port to host machine -RUN npm run build -- --mode ${MODE} +RUN npm run build -- --mode ${MODE} # Use nginx for serving build FROM nginx:1.19-alpine diff --git a/Apps/frontend/src/components/TimeSweepSlider.svelte b/Apps/frontend/src/components/TimeSweepSlider.svelte index f530069a..cb4fa443 100644 --- a/Apps/frontend/src/components/TimeSweepSlider.svelte +++ b/Apps/frontend/src/components/TimeSweepSlider.svelte @@ -2,17 +2,24 @@ import { timeSweep } from "../stores"; import { NUM_CHANNELS } from "../const"; export let channel; - + export let isCommon = false; const handleChange = () => { if (isCommon) { - for (let index=0; index
- +
diff --git a/Apps/frontend/src/components/Waves.svelte b/Apps/frontend/src/components/Waves.svelte index 56d3bf77..b12b3a6e 100644 --- a/Apps/frontend/src/components/Waves.svelte +++ b/Apps/frontend/src/components/Waves.svelte @@ -72,10 +72,10 @@ webGLPlot.clear(); }; - export const updateBuffer = (samples) => { + export const updateBuffer = (samples, startIndex, endIndex) => { for ( - let channelIndex = 0; - channelIndex < channelSamples.length; + let channelIndex = startIndex; + channelIndex < endIndex; channelIndex++ ) { if (!startStopLine[channelIndex]) { @@ -103,7 +103,13 @@ bufferCounter++; if (bufferCounter >= LOG_AFTER) { - console.log('Updated ' + LOG_AFTER + ' times in ' + (currentTime() - startTime) + ' ms.'); + console.log( + "Updated " + + LOG_AFTER + + " times in " + + (currentTime() - startTime) + + " ms." + ); resetLogVars(); } }; diff --git a/Apps/frontend/src/const.js b/Apps/frontend/src/const.js index 1df13f44..9b7cd2f3 100644 --- a/Apps/frontend/src/const.js +++ b/Apps/frontend/src/const.js @@ -32,7 +32,7 @@ export const LINE_THICKNESS_SMALL = 0.002; export const LINE_THICKNESS_BIG = 0.008; export const NUM_CHANNELS = 10; -export const MIN_SWEEP = 0.5; // <= 1 +export const MIN_SWEEP = 0.1; // <= 1 export const MAX_SWEEP = 2.0; // >= 1 export const MIN_AMPLITUDE = 0.0; export const MAX_AMPLITUDE = NUM_INTERVALS_HORIZONTAL / 2; diff --git a/Apps/frontend/src/views/Indicators.svelte b/Apps/frontend/src/views/Indicators.svelte index 42737c8f..dfbe237c 100644 --- a/Apps/frontend/src/views/Indicators.svelte +++ b/Apps/frontend/src/views/Indicators.svelte @@ -9,7 +9,7 @@ INDICATOR_ZERO_LINE_COLOR, LINE_COLORS_RGBA, NUM_CHANNELS, - NUM_INTERVALS_HORIZONTAL + NUM_INTERVALS_HORIZONTAL, } from "../const"; import { roundVoltage } from "../helper"; @@ -29,19 +29,42 @@ * * @param {number[]} samples */ - export const update = (samples) => { + export const update = (samples, startIndex) => { clearCanvas(); drawGlobalZeroLine(); - for (let channel = 0; channel < samples.length; channel++) { + + for (let channel = 0; channel < NUM_CHANNELS; channel++) { if (startStopLine[channel]) { - updateCurrentMinMax(samples[channel], channel); + updateCurrentMinMax(samples[startIndex + channel], channel); } - const transformedCurrent = transformSampleToYCoord(current[channel], offsets[channel], scalings[channel]); - const transformedMin = transformSampleToYCoord(min[channel], offsets[channel], scalings[channel]); - const transformedMax = transformSampleToYCoord(max[channel], offsets[channel], scalings[channel]); - const transformedZero = transformSampleToYCoord(0, offsets[channel], scalings[channel]); - drawIndicator(channel, transformedCurrent, LINE_COLORS_RGBA[channel]); - drawMinMaxZeroLines(channel, transformedMin, transformedMax, transformedZero, LINE_COLORS_RGBA[channel]); + const transformedCurrent = transformSampleToYCoord( + current[channel], + offsets[channel], + scalings[channel] + ); + const transformedMin = transformSampleToYCoord( + min[channel], + offsets[channel], + scalings[channel] + ); + const transformedMax = transformSampleToYCoord( + max[channel], + offsets[channel], + scalings[channel] + ); + const transformedZero = transformSampleToYCoord( + 0, + offsets[channel], + scalings[channel] + ); + //drawIndicator(channel, transformedCurrent, LINE_COLORS_RGBA[channel]); + drawMinMaxZeroLines( + channel, + transformedMin, + transformedMax, + transformedZero, + LINE_COLORS_RGBA[channel] + ); writeText(channel, min[channel], max[channel]); } }; diff --git a/Apps/frontend/src/views/Oscilloscope.svelte b/Apps/frontend/src/views/Oscilloscope.svelte index e22d3a95..04dd92ce 100644 --- a/Apps/frontend/src/views/Oscilloscope.svelte +++ b/Apps/frontend/src/views/Oscilloscope.svelte @@ -22,9 +22,20 @@ let btnOnOff; let scalesY = Array(NUM_CHANNELS).fill(1); // 1V per horizontal line let indicatorElement; + /** Websocket for connection to backend */ let socket; - + /** Flag for enabled and updating canvas */ let isEnabled = false; + /** Number of received packages before they are computed */ + let packageCounterPreCompute = 0; + /** Number of packages per second */ + let pps = 0; + /** Duration of computing and updating one package */ + let packageComputeTime = 0; + /** Duration of computing and updating one channel window within the package */ + let windowComputeTime = 0; + /** Number of chunks in a package */ + let chunkNumber = 0; // ----- Svelte lifecycle hooks ----- onMount(() => { @@ -40,25 +51,78 @@ // -----business logic functions ----- const createSocket = () => { + console.log("Connecting to :" + import.meta.env.VITE_BACKEND_WEBSOCKET); let socket = new WebSocket(import.meta.env.VITE_BACKEND_WEBSOCKET); socket.binaryType = "arraybuffer"; return socket; }; + /** + * On receiving a socket message, update buffer of waves. + * + * @param {MessageEvent} messageEvent - has poperty (Float64Array) data + */ const socketOnMessage = (messageEvent) => { - let samples = new Float64Array(messageEvent.data); if (!isEnabled) return; - waveElement.updateBuffer(samples); - indicatorElement.update(samples); + packageCounterPreCompute += 1; + + var chunkCounter = 0; + var startPackage = window.performance.now(); + + let samples = new Float64Array(messageEvent.data); + for (let index = 0; index < samples.length; index += NUM_CHANNELS) { + var startWindow = window.performance.now(); + waveElement.updateBuffer(samples, index, index + NUM_CHANNELS); + if (index % 1000 == 0) indicatorElement.update(samples, index); + var endWindow = window.performance.now(); + + ++chunkCounter; + updateWindowComputeTime(startWindow, endWindow); + } + + var endPackage = window.performance.now(); + updatePackageComputeTime(startPackage, endPackage); + chunkNumber = chunkCounter; }; const socketOnClose = (closeEvent) => logSocketCloseCode(closeEvent.code); + + /** + * Calculates the packages per second received on the web socket + */ + function calculatePackagesPerSecond() { + pps = packageCounterPreCompute; + packageCounterPreCompute = 0; + } + + /** + * Calculate the duration between start and end of + * TODO implement historic average over e.g. last 20 packages + * @param start start timestamp + * @param end end timestamp + */ + function updatePackageComputeTime(start, end) { + packageComputeTime = end - start; + } + /** + * Calculate the duration between start and end of single index windows on a package + * TODO implement historic average over e.g. last 20 packages + * @param start start timestamp + * @param end end timestamp + */ + function updateWindowComputeTime(start, end) { + windowComputeTime = end - start; + } + + setInterval(function () { + calculatePackagesPerSecond(); + }, 1000);
@@ -96,8 +160,8 @@
Start/Stop -
-
+
+
Channels {#each { length: NUM_CHANNELS } as _, index}
Thickness -
-
+
+
Channels {#each { length: NUM_CHANNELS } as _, index}
Offset -
-
+
+
Channels {#each { length: NUM_CHANNELS } as _, index}
Time Sweep -
+
Common Channels @@ -150,8 +214,8 @@
Amplitude -
-
+
+
Channels {#each { length: NUM_CHANNELS } as _, index}
+
+

+ Package Size: {chunkNumber} | PPS: {pps * chunkNumber} | Updatetime/Window: {windowComputeTime.toFixed( + 5 + )} ms | Updatetime/Package: {packageComputeTime.toFixed(5)} ms +

+
diff --git a/Deployments/web_deployment/dev/docker-compose.yml b/Deployments/web_deployment/dev/docker-compose.yml index 7504dd0d..dac2368a 100644 --- a/Deployments/web_deployment/dev/docker-compose.yml +++ b/Deployments/web_deployment/dev/docker-compose.yml @@ -8,7 +8,7 @@ services: environment: - HOST=0.0.0.0:34254 - TARGET=backend:34255 - - PPS=100.0 + - PPS=20000.0 - SIG_FREQ=1.0 ports: - 34254:34254 diff --git a/Deployments/web_deployment/int/docker-compose.yml b/Deployments/web_deployment/int/docker-compose.yml index c60792db..6b6e38c2 100644 --- a/Deployments/web_deployment/int/docker-compose.yml +++ b/Deployments/web_deployment/int/docker-compose.yml @@ -8,7 +8,7 @@ services: environment: - HOST=0.0.0.0:34256 - TARGET=backend:34257 - - PPS=100.0 + - PPS=20000.0 - SIG_FREQ=1.0 ports: - 34256:34256 diff --git a/Deployments/web_deployment/prod/docker-compose.yml b/Deployments/web_deployment/prod/docker-compose.yml index ae7256ff..9dd45c32 100644 --- a/Deployments/web_deployment/prod/docker-compose.yml +++ b/Deployments/web_deployment/prod/docker-compose.yml @@ -8,7 +8,7 @@ services: environment: - HOST=0.0.0.0:34258 - TARGET=backend:34259 - - PPS=100.0 + - PPS=20000.0 - SIG_FREQ=1.0 ports: - 34258:34258