Über WebAssembly
WebAssembly(WASM) ist ein portables binäres Befehlsformat, das im Browser oder auf einem Server ausgeführt werden kann. Es wurde im Hinblick auf Leistung und Sicherheit entwickelt. WebAssembly kann aus anderen Programmiersprachen wie C/C++, C#, Rust, Go und vielen anderen kompiliert werden.
Das Ziel war es, JavaScript zu ergänzen und nicht zu ersetzen. WebAssembly ist dafür gedacht, schwere und rechenintensive Aufgaben einer Webanwendung auszuführen. Dadurch kann sich JavaScript wieder auf die Interaktivität des Browsers konzentrieren und WebAssembly die schwere Arbeit überlassen.
WASM wurde ursprünglich für das Web entwickelt. Es gibt eine Vielzahl von Anwendungsfällen, denken Sie an Bild-/Videobearbeitung, Spiele, VR, Simulationen und mehr.
Dank WebAssembly System Interface(WASI) fängt WASM an, außerhalb des Browsers aufzutauchen. WASM+WASI hat viel Potenzial, siehe den Tweet von Solomon Hykes, Mitbegründer von Docker.
WebAssembly wird schon seit langem von Anwendungen wie AutoCad und Figma verwendet.
Golang WebAssembly
WebAssembly kann von Golang selbst oder mit TinyGo kompiliert werden. Zum Zeitpunkt der Erstellung dieses Dokuments ist Go Version 1.18 die neueste Version und unterstützt WASI nicht. Wenn Sie WASI kompilieren möchten, müssen Sie TinyGo verwenden.
Wie Sie WebAssembly mit Go im Browser verwenden
Wir werden ein einfaches Go-Hashing-Programm erstellen, mit dem wir SHA512-Hash-Werte mit Go im Browser verarbeiten können.
Lassen Sie uns mit der Verzeichnisstruktur beginnen:
go-wasm-example
├── static
└── cmd
├── server
└── wasm
Erstellen Sie die Haupt-Go-Datei
Erstellen Sie eine Datei main.go in go-wasm-example/cmd/wasm und fügen Sie den folgenden Code hinzu:
package main
import (
"crypto"
_ "crypto/sha512"
"encoding/hex"
"fmt"
"syscall/js"
)
func main() {
done := make(chan struct{}, 0)
js.Global().Set("wasmHash", js.FuncOf(hash))
<-done
}
func hash(this js.Value, args []js.Value) interface{} {
h := crypto.SHA512.New()
h.Write([]byte(args[0].String()))
return hex.EncodeToString(h.Sum(nil))
}
Lassen Sie uns die Hauptfunktion aufschlüsseln.
Der Code done := make(chan struct{}, 0) & <-done ist ein Go-Kanal. Ein Kanal wartet darauf, dass Daten an ihn gesendet werden, und wird verwendet, um das Programm am Laufen zu halten.
Die Funktion js.Global().Set("wasmHash", hash) erstellt eine globale JS-Funktion, die die Go-Hash-Funktion für JavaScript sichtbar macht.
In der Hash-Funktion sehen Sie (this js.Value, args []js.Value) werden die Argumente von JS als Array übergeben.
Um den Wert des Arguments zu casten, verwenden Sie .String() oder .Int(). Sie können mehr darüber in den syscall/js docs lesen.
Kompilieren Sie sie zu einer .wasm-Datei
Um es in WASM kompilieren zu können, müssen Sie GOOS=js GOARCH=wasm zum Build-Befehl hinzufügen.
Dies weist Go an, in eine .wasm-Datei zu kompilieren.
GOOS=js GOARCH=wasm go build -o static/main.wasm cmd/wasm/main.go
Sie sehen nun die Datei main.wasm im Verzeichnis static.
Unterstützung für wasm_exec.js
Die wasm_exec.js wird von Go bereitgestellt und dient zum Abrufen und Ausführen des main.wasm Go-Codes im Browser.
Die JavaScript-Datei befindet sich im Ordner GOROOT. Um sie in das statische Verzeichnis zu kopieren, verwenden Sie den folgenden Befehl:
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./static
Erstellen Sie die index.html
Wir haben jetzt die .wasm-Binärdatei und den wasm_exec.js-Code. Den wir nun in eine HTML-Seite laden werden.
Lassen Sie uns die Datei index.html im Verzeichnis static erstellen.
Fügen Sie den folgenden Code in die index.html ein:
<html>
<head>
<meta charset="utf-8"/>
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
</script>
</head>
<body>
<div>
<label for="inputField">Enter value</label>
<input id="inputField" name="Hash" type="text">
<div id="outputHash" style="font-size: 20px"></div>
</div>
<script>
var inputField = document.querySelector('#inputField')
var outputHash = document.querySelector('#outputHash')
inputField.addEventListener('keyup', function() {
outputHash.innerHTML = wasmHash(inputField.value) // The function 'wasmHash' is defined in the Go code
});
</script>
</body>
</html>
Im Head-Code finden Sie das JavasScript zur Ausführung des Go WASM-Codes. Weitere Informationen dazu finden Sie hier: https://github.com/golang/go/wiki/WebAssembly#getting-started
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
</script>
Webserver
Um die HTML-Datei ausliefern zu können, benötigen Sie einen Webserver.
Wir erstellen also einen einfachen Webserver und fügen den folgenden Code in cmd/webserver/main.go
package main
import (
"log"
"net/http"
)
func main() {
fs := http.FileServer(http.Dir("./static"))
http.Handle("/", fs)
log.Println("Listening on http://localhost:3000/index.html")
err := http.ListenAndServe(":3000", nil)
if err != nil {
log.Fatal(err)
}
}
Jetzt können wir die soeben erstellte HTML-Datei ausliefern, indem wir sie ausführen:
go run ./cmd/webserver/main.go
Navigieren Sie zu http://localhost:3000/index.html
Jetzt können Sie einen Textwert in das Eingabefeld eingeben und Go wird Ihren Wert hashen.
Fazit
WebAssembly hat den Vorteil, dass es innerhalb und außerhalb des Browsers portabel ist. Es handelt sich um eine kompilierte Sprache, so dass Fehler bereits vor der Laufzeit erkannt werden.
Ich denke, dass WebAssembly bei der Portierung von Desktop-Anwendungen auf den Browser wirklich glänzt. Zum Beispiel für Anwendungen, die in einer Sprache wie C/C++ geschrieben wurden.
Weitere Informationen über Go WebAssembly finden Sie hier
Den Quellcode dieses Blogs finden Sie hier: https://github.com/tiborhercz/go-wasm-example
Verfasst von

Tibor Hercz
Tibor is a Cloud Consultant specialized in AWS with a strong background in Software engineering and has a passion for Compute, Networking and Security. His goal is to create simple Cloud Solutions that increases the efficiency and overall happiness of the teams and business. Sharing knowledge is important to him, so you will see him blogging and sharing knowledge about solutions he has built.
Unsere Ideen
Weitere Blogs
Contact




