Sie haben wahrscheinlich schon von Blazor gehört und dass es WebAssembly verwendet, um .NET-Code in einem Browser auszuführen. Aber wussten Sie, dass Sie WebAssembly für viel mehr verwenden können? In diesem Beitrag zeigen wir Ihnen ein paar coole Dinge, die Sie mit WebAssembly tun können.
Was ist WebAssembly?
WebAssembly wurde als Sprache zur Ausführung von Binärcode innerhalb eines Webbrowsers entwickelt. Anwendungen, die in WebAssembly ausgeführt werden, laufen isoliert, genau wie Docker-Container. Durch den Einsatz von Virtualisierung kann ein WebAssembly-Programm ohne Änderungen auf verschiedene Betriebssysteme und Prozessoren übertragen werden. Es läuft auf Windows, Mac, Linux und Geräten wie dem Raspberry Pi gleichermaßen gut. Dies ist ein großer Unterschied zu Containern, die für bestimmte Betriebssysteme und Prozessortypen erstellt werden.
WebAssembly, oder 'Wasm', wurde von Mozilla erfunden und wird nun von der ByteCode Alliance, einer Gruppe von Unternehmen wie Microsoft, Intel und Google, vorangetrieben. Derzeit unterstützen Chrome, Edge, Safari und Firefox die Ausführung von WebAssembly. Da es sich um ein kompaktes Binärformat handelt, wird es mit geringem Overhead und nahezu nativer Geschwindigkeit ausgeführt. Im Vergleich zu JavaScript laufen WebAssembly-Anwendungen in der Regel viel schneller. Viele beliebte Programmiersprachen können in WebAssembly kompiliert und im Internet ausgeführt werden. Zu den unterstützten Sprachen gehören Rust, Python, Go und C. Sie können sogar die .NET Mono CLR in WebAssembly ausführen und sie zur Ausführung regulärer .NET DLLs verwenden. Blazor funktioniert derzeit auf diese Weise. Microsoft experimentiert auch mit einer .NET-Laufzeitumgebung, die C# nach Wasm kompiliert.
Mozilla hat WebAssembly so konzipiert, dass es mit JavaScript koexistiert und zusammenarbeitet, um ein gutes Web-Erlebnis zu bieten. Eine Datei, die WebAssembly-Code enthält, wird als Modul bezeichnet. Eine Instanz eines Moduls wird in einer Sandbox-Ausführungsumgebung ausgeführt. Das Sandboxing stellt sicher, dass WebAssembly nicht auf sensible Daten wie Dateien und Netzwerkressourcen zugreifen kann, ohne die ausdrückliche Zustimmung der Hosting-Umgebung, also in der Regel Ihres Webbrowsers. WebAssembly tut dies, indem es Funktionen von und zu seinem Host importiert und exportiert.
Jenseits des Browsers
WebAssembly macht keine Annahmen über die Hostumgebung, auf der es ausgeführt wird. Das bedeutet, dass WebAssembly auch außerhalb eines Browsers ausgeführt werden kann. Das 'WebAssembly System Interface' oder 'WASI' ermöglicht dies. WASI ist eine API, die WebAssembly mit Betriebssystemfunktionen wie dem Zugriff auf das Dateisystem und der Kommunikation über Netzwerke versorgt. Dies funktioniert über die bereits erwähnten Funktionsimporte. Die meisten modernen Browser implementieren die WASI-Schnittstelle, und es gibt auch einige eigenständige Implementierungen. Eine eigenständige WASI-Laufzeitumgebung bedeutet, dass ein Browser nicht mehr erforderlich ist, um WebAssembly-Code auszuführen. Wie bei jeder guten OSS-Technologie gibt es eine ganze Reihe von WASI-Laufzeiten, aus denen Sie wählen können: wasmtime, WAMR, Wasmer, WasmEdgeRuntime, Wasm3 und andere. Für diesen Artikel haben wir einen Host namens wasmtime ausgewählt.
Entwickeln mit WebAssembly
Wahrscheinlich sind Sie schon ganz begierig darauf, WebAssembly-Code auszuführen. Wir beginnen mit der Erstellung und Ausführung eines einfachen "Hallo Welt"-WebAssembly-Programms in einem Browser unter Verwendung der Programmiersprache Rust unter Linux. Wenn Sie mit Windows arbeiten, können Sie WSL2 verwenden, um die Schritte in diesem Beitrag auszuführen.
Ausführen von WebAssembly in Ihrem Browser
Wir werden etwas Rust-Code erstellen und ihn in WebAssembly kompilieren. Wenn Sie diese noch nicht installiert haben, führen Sie bitte diesen Befehl aus, um die Rust-Tools zu installieren:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Wir möchten ein interaktives Programm erstellen, das dem Endbenutzer bei der Ausführung ein Nachrichtenfeld anzeigt. Um dies innerhalb eines Browsers zu tun, werden wir JavaScript-Funktionen importieren. Dazu benötigen wir eine Möglichkeit, von WebAssembly zu JavaScript zu wechseln. Hierfür können wir wasm-pack verwenden. Führen Sie diesen Befehl aus, um wasm-pack zu installieren:
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh Lassen Sie uns nun eine einfache Hello-World-Bibliothek in Rust erstellen, indem wir sie ausführen: cargo new --lib hello-wasm Wechseln Sie das Verzeichnis in den neu erstellten Programmordner: cd hallo-wasm/
Wechseln Sie das Verzeichnis in den neu erstellten Programmordner:
cd hallo-wasm/
Der Ordner 'hello-wasm' enthält eine Datei namens Cargo.toml, in der beschrieben wird, wie das Projekt erstellt wird, und einen Ordner 'src' mit einer Datei namens lib.rs, die wir jetzt ändern werden. Ändern Sie die Datei, um ein Programm zu erstellen, das beim Ausführen'Hello world!' ausgibt. Verwenden Sie Ihren bevorzugten Texteditor, um den Code zu ändern, wie er in Abbildung 1:
Die erste Zeile importiert eine bestehende Bibliothek namens 'prelude', so dass wir die Funktionen im Code nach dem 'use' verwenden können' Anweisung. Das Tool wasm-pack verwendet das Attribut '#[ wasm_bindgen]', die es Rust ermöglicht, JavaScript aufzurufen. Die Funktion ' alert' existiert in JavaScript und wird in Rust durch die Verwendung der 'extern' Schlüsselwort. Der letzte Abschnitt des Codes gibt eine Rust-Methode an JavaScript weiter, indem er das Schlüsselwort ' pub'-Schlüsselwort für die Funktion namens 'greet'. Nach der Kompilierung haben wir ein WebAssembly-Programm, das eine Funktion 'greet' zur Verfügung stellt. Wir werden JavaScript auf einer Webseite verwenden, um diese Methode aufzurufen. Wenn sie ausgeführt wird, ruft sie die JavaScript-Funktion 'alert' auf, um ein Nachrichtenfeld zu erstellen.
Schließlich ändern Sie die Datei Cargo.toml , um die Abhängigkeit zum Tool wasm-pack mit dem Inhalt aus Abbildung 2.
Jetzt können wir wasm-pack ausführen, um das Projekt mit diesem Befehl zu kompilieren:
wasm-pack build --target web
Nach etwa einer halben Minute sollten Sie eine ähnliche Ausgabe wie diese sehen:
[INFO]: :-) Erledigt in 27.08s [INFO]: :-) Ihr wasm pkg ist bereit zur Veröffentlichung unter /home/user/xpirit/magazine/rust/hello-wasm/pkg.
Wenn Sie sich die Dateien in diesem Ausgabeverzeichnis ansehen, sollten Sie eine Datei mit dem Namen 'hello_wasm.js' und eine mit dem Namen 'hello_wasm_bg.wasm' sehen. Die wasm-Datei enthält den Rust-Code, der in WebAssembly kompiliert wurde. Die JavaScript-Datei enthält alles, was erforderlich ist, um Ihre WebAssembly-Datei als Modul in den Browser zu laden. Lassen Sie uns die JavaScript-Datei in einer HTML-Datei ausführen, um zu zeigen, dass sie funktioniert. Erstellen Sie eine Datei namens'index.html' innerhalb von den Ordner pkg, mit dem Inhalt von Abbildung 3
Wie Sie sehen können, verwendet die Webseite JavaScript, um die Methode 'greet' in WebAssembly aufzurufen. Um zu sehen, wie das funktioniert, sehen Sie sich die Datei 'hello_wasm.js' an.
Sie benötigen einen Webserver, um diese Seite und ihr JavaScript auszuführen. Das Skript wird nicht ausgeführt, wenn Sie die lokale Datei direkt von der Festplatte öffnen. Wenn Sie VS Code verwenden, können Sie die Erweiterung 'Live Server' von Ritwick Dey verwenden. Wenn das Skript ausgeführt wird, sollten Sie etwas ähnliches sehen wie den Bildschirm aus Abbildung 4.
Herzlichen Glückwunsch! Sie haben gerade Ihr erstes WebAssembly-Modul erstellt, das im Browser gehostet wird!
WebAssembly ohne Browser ausführen
WebAssembly kann auch lokal auf Ihrem Rechner ausgeführt werden, indem Sie eine eigenständige Laufzeitumgebung verwenden. Der Grund dafür ist, dass WebAssembly sich auf die WebAssembly-Systemschnittstelle (WASI) stützt, um mit dem zugrunde liegenden Betriebssystem zu kommunizieren. Die WebAssembly-Systemschnittstelle ist nicht von Browsern abhängig und benötigt kein JavaScript, um ausgeführt zu werden.
Für das nächste Beispiel werden wir also kein Javascript mehr verwenden, sondern eine Konsolenanwendung erstellen, die über WASI direkt auf Ihrem Betriebssystem läuft.
Wir werden den Rust-Code in diesem Beispiel in WASI-kompatibles WebAssembly kompilieren. Wir werden die JavaScript-Aufrufe durch Konsolenein- und -ausgaben ersetzen, indem wir die Streams stdin und stdout verwenden. Zuvor haben wir Rust installiert. Dabei wurden jedoch nicht die Tools installiert, die für die Kompilierung zu WASI-kompatiblem WebAssembly erforderlich sind. Dafür benötigen wir eine neue Bibliothek namens 'wasm32-wasi'. Installieren Sie sie mit diesem Befehl:
rustup target add wasm32-wasi
Nachdem Sie nun das richtige Build-Target installiert haben, erstellen wir ein neues Projekt. Dazu können Sie den folgenden Befehl ausführen:
Fracht neue hellowasi Wechseln Sie das Verzeichnis in den neu erstellten Programmordner: cd hellowasi/ Als nächstes kompilieren Sie das Programm in WASI-kompatibles WebAssembly, indem Sie es ausführen: cargo build --release --target wasm32-wasi Um die kompilierte WebAssembly auszuführen, benötigen wir einen eigenständigen Host. Wir werden dafür wasmtime verwenden. Installieren Sie wasmtime mit: curl https://wasmtime.dev/install.sh -sSf | bash
Führen Sie das Programm hellowasi mit aus:
wasmtime ./target/wasm32-wasi/release/hellowasi.wasm
Die Ausgabe sollte"Hallo, Welt!" lauten.
Herzlichen Glückwunsch! Sie haben gerade Ihr erstes natives WebAssembly-Programm erstellt und ausgeführt.
Ausführen von WebAssembly mit WAGI
Wir haben jetzt ein schönes Konsolenprogramm, das seine Ausgabe in den stdout-Stream schreibt. Was aber, wenn Sie APIs in WebAssembly entwickeln und auf einer beliebigen Plattform hosten möchten? An dieser Stelle kommt das derzeitige experimentelle WebAssembly Gateway Interface (WAGI) ins Spiel. Auf der WAGI-Website heißt es : "WAGI ermöglicht es Ihnen, WebAssembly WASI-Binärdateien als HTTP-Handler auszuführen.
"Wussten Sie, dass Deis Labs früher Deis hieß und die Gründer von Helm für Kubernetes war. Nach der Übernahme durch Microsoft im April 2017 wurde es zu Deis Labs. Deis Labs führt derzeit viele experimentelle Programme durch, die sich um WebAssembly und Kubernetes drehen."
"Wenn es WASM+WASI schon 2008 gegeben hätte, hätten wir Docker nicht entwickeln müssen. Das zeigt, wie wichtig es ist. Webassembly auf dem Server ist die Zukunft der Datenverarbeitung. Eine standardisierte Systemschnittstelle war das fehlende Glied. Hoffen wir, dass WASI dieser Aufgabe gewachsen ist!"
- Solomon Hyke, Mitbegründer von Docker
Ähnlich wie wasm-pack als Brücke zwischen JavaScript und WebAssembly fungiert, verbindet WAGI die HTTP-Anfragen und -Antworten mit den stdin- und stdout-Streams Ihres Programms.
Um mit WAGI zu beginnen, laden Sie die neueste Version von WAGI release herunter und entpacken sie. Als nächstes müssen wir eine Konfigurationsdatei hinzufügen, um WAGI mitzuteilen, wo sich das WebAssembly-Programm befindet, das wir für jede angeforderte URL ausführen möchten. In unserem Beispiel verwenden wir den Root-Pfad unter "/".
Erstellen Sie eine wagi.toml-Datei mit dem Inhalt aus Abbildung 5.
Da WAGI als HTTP-Server fungiert, müssen wir sicherstellen, dass die erforderlichen Content-Type-Header in die Ausgabedatenströme in unserem WebAssembly-Programm geschrieben werden. Stellen Sie sicher, dass Ihre Datei main.rs wie folgt aussieht Abbildung 6.
Kompilieren Sie das Programm neu mit:
cargo build --release --target wasm32-wasi
Danach sollten Sie in der Lage sein, WAGI mit dem folgenden Befehl zu starten, um Ihr WebAssembly-Programm auszuführen:
wagi -c wagi.toml
Wenn WAGI läuft, können Sie localhost:3000 besuchen, um die Ausgabe zu sehen. Das Ergebnis sollte in etwa so aussehen Abbildung 7.
Herzlichen Glückwunsch! Sie haben gerade Ihren ersten WebAssembly-API-Server mit WAGI erstellt und ausgeführt.
Umzug in die Cloud
Die Ausführung von Code in einer leichtgewichtigen isolierten Sandbox kommt Ihnen vielleicht bekannt vor. Die Art und Weise, wie der Code in WebAssembly ausgeführt wird, hat viel Ähnlichkeit mit der Art und Weise, wie wir Code in Containern ausführen. Was also, wenn wir unsere WebAssembly-API in großem Umfang in der Cloud ausführen möchten? Das können wir mit Azure Kubernetes Service und einem experimentellen Dienst namens Krustlet, der von Deis Labs entwickelt wurde. Krustlet fungiert als Kubernetes-Knoten, mit dem Sie WebAssembly-Programme auf Kubernetes ausführen können. Ähnlich wie Kubernetes-Knoten Container auf der Grundlage von Images ausführen, die in einer OCI-Registry gespeichert sind, führt Krustlet WebAssembly-Programme auf der Grundlage von OCI-Artefakten (in unserem Fall die wasm-Datei) aus.
OCI-Artefakte unterstützen viele verschiedene Formate. Abgesehen von Container-Images können Sie Ihr WebAssembly-Programm auch als OCI-Artefakte in einer geeigneten Registry (z.B. Azure Container Registry) speichern. Dazu benötigen Sie ein weiteres Programm namens wasm-to-oci.
Laden Sie die neueste Version von GitHub WASM zu oci releases herunter und installieren Sie sie dann mit den folgenden Befehlen:
mv linux-amd64-wasm-to-oci wasm-to-oci chmod +x wasm-to-oci sudo cp wasm-to-oci /usr/local/bin Stellen Sie sicher, dass Azure Container Registry (ACR) zum Testen zur Verfügung steht und aktivieren Sie die Funktion "Anonymer Zugriff", damit WAGI ohne Anmeldung darauf zugreifen kann. Melden Sie sich bei ACR an und übertragen Sie Ihr WebAssembly-Programm mit in ACR: az acr login --name acrwasmwasi az acr update --name acrwasmwasi --anonymous-pull-enabled true wasm-to-oci push ./target/wasm32-wasi/release/hellowasi.wasm acrwasmwasi.azurecr.io/hellowasi:v1 Hinweis: Stellen Sie sicher, dass Sie acrwasmwasi durch den Namen Ihrer Container-Registrierung ersetzen. WAGI, das wir im vorangegangenen Absatz verwendet haben, unterstützt von Haus aus OCI-Artefakte als Quelle für WebAssembly-Code. Sie können dies versuchen, indem Sie die zuvor erstellte Datei wagi.toml wie folgt aktualisieren Abbildung 8.
Führen Sie WAGI mit diesem Befehl erneut aus:
wagi -c wagi.toml
Wenn dies erfolgreich ist, sollte die Ausgabe im Browser auf localhost:3000 genauso aussehen wie in Abbildung 7.
Ausführen von WebAssembly auf AKS
Da Deis Labs zu Microsoft gehört, ist die Vorschauunterstützung für Krustlet-Knoten bereits in Azure verfügbar. Wenn Sie mehr darüber erfahren und es selbst ausprobieren möchten, folgen Sie dem Walkthrough zu Use wasi node pools
Fazit
Sie haben schon einige interessante Anwendungen von WebAssembly gesehen. Man könnte es als eine hochsichere Möglichkeit betrachten, Code in einer isolierten Sandbox lokal, im Browser, in Kubernetes usw. auszuführen.
Aber es gibt einige Dinge, die Sie beachten sollten...
WebAssembly-Code in einem Binärformat ist schwer zu lesen. Es ist schwierig, von außen zu erkennen, was der Code in einer Wasm-Datei tut, insbesondere wenn er auch noch verschleiert ist. Kombiniert man dies mit der hohen Ausführungsgeschwindigkeit und der Browserunterstützung, wird schnell klar, wie WebAssembly für unanständige Dinge wie das Ausführen von Krypto-Minern im Webbrowser eines unwissenden Benutzers verwendet werden kann. Zum Zeitpunkt der Erstellung dieses Artikels gibt es noch keine Sicherheitsscanner-Plattformen, die Bilder auf Malware und Schwachstellen überprüfen.
Die meisten oder alle aktuellen Hosts sind anfällig für Angriffe wie SPECTRE, so dass die hier gezeigten Beispiele derzeit nicht in einer Produktionsumgebung verwendet werden sollten.
Wenn diese Sicherheitsrisiken entschärft werden, könnte WebAssembly in Zukunft das nächste große Ding nach Containern werden.
Relevante Links
| Link | Was |
| https:www.hacks.mozilla.org/2018/10/webassemblys-post-mvp-future | Beschreibt den aktuellen Stand und die Zukunftspläne für WebAssembly |
| https:www.bytecodealliance.org | Website der ByteCode Alliance. |
| https:www.github.com/bytecodealliance/wasmtime-dotnet | Wasmtime für .NET |
| https:www.deislabs.io | Website von Deis Labs, Teil von Microsoft. |
| https:www.github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM | Experimentelle Microsoft-Laufzeitumgebung, die C# zu Wasm kompiliert. |
Ein Zitat, das Sie in ein quadratisches Feld einfügen können:
Hätte es WASM+WASI im Jahr 2008 gegeben, hätten wir Docker nicht erschaffen müssen. So wichtig ist es. Webassembly auf dem Server ist die Zukunft der Datenverarbeitung. Eine standardisierte Systemschnittstelle war das fehlende Glied. Hoffen wir, dass WASI dieser Aufgabe gewachsen ist!
Solomon Hyke, Mitbegründer von Docker
Ein weiteres Zitat das Sie irgendwo in ein quadratisches Kästchen setzen können:
Wussten Sie, dass Deis Labs früher Deis hieß und die Gründer von Helm für Kubernetes war. Nach der Übernahme durch Microsoft im April 2017 wurde es zu Deis Labs. Deis Labs führt derzeit viele experimentelle Programme durch, die sich um WebAssembly und Kubernetes drehen.
Verfasst von
Loek Duys
Cloud software architecture
Unsere Ideen
Weitere Blogs
Contact




