# Rust JavaScript Einbindung ```rust async fn get_mjs() -> impl IntoResponse { Response::builder() .header("content-type", "application/javascript;charset=utf-8") .body(tokio::fs::read_to_string("src/index.mjs").await.unwrap()) .unwrap() } ``` Der Code definiert eine asynchrone Funktion mit dem Namen `get_mjs()`, die ein `impl IntoResponse`-Objekt zurückgibt. Der `IntoResponse`-Trait ermöglicht es, einen Typen in einen HTTP-Response-Typen zu konvertieren, den der Webserver senden kann. Im professionellen betrieb sollte `impl IntoResponse` vermieden werden, da die Fehlerbehandlung schnell unübersichtlich werden kann. Da wir unser Projekt in kleinem Rahmen halten, ist es in Ordnung diese Methodik anzuwenden. In der Funktion wird zuerst ein `ResponseBuilder`-Objekt erstellt, das eine `content-type`-Headerzeile mit dem MIME-Typ `application/javascript` und Zeichensatz `utf-8` enthält. Anschließend wird der Inhalt der Datei `src/index.mjs` asynchron aus dem Dateisystem gelesen und als Body der HTTP-Responses festgelegt. Schließlich wird die vollständige HTTP-Response mit `unwrap()` zurückgegeben. Wenn das Lesen der Datei fehlschlägt, wird eine `panic!()`-Meldung ausgegeben. An dieser Stelle könnte man den Quellcode durch besseres Error-Handling verbessern, da `panics` im Nutzergebrauch in der Regel nicht zu hilfreicher Fehlerbehandlung führen. **Das Skript in `src/index.mjs` zur Beschreibung:** ```js import { h, render } from "https://unpkg.com/preact?module"; // Import Preact import htm from "https://unpkg.com/htm?module"; // Import htm const html = htm.bind(h); // Render CPU Stats function CpuStats(props) { return html` ${props.cpus.map((cpu, index) => { // Create a Graph for every CPU return html`
Core ${index}
${cpu.toFixed(2)}%
`; })} `; } // Render Memory Usage function MemStats(props) { // Create the Memory Graph return html`
Total Memory: ${(props.memory["totalMemory"]/1000000).toFixed(0)} Mb
Used Memory: ${(props.memory["usedMemory"]/1000000).toFixed(0)} Mb
Free Memory: ${((props.memory["totalMemory"]-props.memory["usedMemory"])/1000000).toFixed(0)} Mb
`; } // Update the page let update = async () => { let response = await fetch("/rest/cpu"); let cpujson = await response.json(); render(html`<${CpuStats} cpus=${cpujson}>`, document.getElementById("cpu_stats")) response = await fetch("/rest/memory"); let memoryjson = await response.json(); render(html`<${MemStats} memory=${memoryjson}>`, document.getElementById("mem_stats")) } update() // Update the page every 200ms. // This could be improved by using a sender-receiver architecture // using a websocket. // Unfortunately, time is precious in this project and this method will do. setInterval(update, 200); ``` Dieser Code verwendet die Bibliotheken [preact](https://preactjs.com) und [htm](https://www.npmjs.com/package/htm) und definiert eine Funktionen `CpuStats` und `MemStats`, die eine Liste von Memory- und CPU-Auslastungswerten als Eingabe erhält und eine HTML-Darstellung dieser Werte erstellt. Die Funktion `update` ruft die REST endpunkte vom Server ab und benutztz die eben genannten Funktionen, um die HTML-Darstellung zu erstellen. Die `setInterval` -Funktion ruft die "update" -Funktion alle 200 Millisekunden auf, um die CPU-Auslastung zu aktualisieren. Die "console.log" -Anweisung dient lediglich zur Ausgabe einer Meldung in der Browserkonsole. Wie im Code Beispiel schon genannt, ist `setInterval` nicht die optimale Lösung in dieser situation, da die Werte von Hand abgefragt werden müssen. Eine elegantere Methode wäre die Verwendung eines Web Sockets, der die Seite wenn neue CPU Werte vorliegen, aktualisiert. Die HTML Seite zum eben genannten Javascript code ist kurz und beinhaltet nur die statischen Elemente, wie Überschrift, Hilfetext und Header. ```html Webserver

Computer Statistics

On this page you can get up-to-date information about the performance of your system.
Use this information to monitor performance and resources.

CPU

Memory

```