Arbeiten mit WebAssembly und Go: fortgeschrittene Integrationstechniken

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Arbeiten mit WebAssembly und Go: fortgeschrittenes Niveau



WebAssembly (WASM) eröffnet neue Horizonte für die Webentwicklung, indem es die Ausführung von hochperformantem Code ermöglicht, der in anderen Sprachen als JavaScript geschrieben wurde. Go (Golang) ist mit seinem Compiler für WASM und seinem einfachen Nebenläufigkeitsmodell ein hervorragender Kandidat für die Erstellung komplexer Webmodule. In diesem Artikel betrachten wir fortgeschrittene Techniken zur Integration von Go und WebAssembly: Arbeit mit Speicher, Übergabe komplexer Datenstrukturen, bidirektionale Kommunikation mit JavaScript und Leistungsoptimierung.



1. Übergabe komplexer Datenstrukturen zwischen Go und JavaScript



Die grundlegende Übergabe von Zahlen und Zeichenketten über syscall/js ist einfach, reicht aber für reale Anwendungen nicht aus. Ein fortgeschrittener Ansatz beinhaltet die Serialisierung komplexer Strukturen (Slices, Maps, benutzerdefinierte Typen) in JSON oder ein binäres Format.



Serialisierung über JSON

Die einfachste und universellste Methode ist die Verwendung von encoding/json. Sie exportieren eine Funktion, die eine JSON-Zeichenkette entgegennimmt, sie in eine Go-Struktur deserialisiert, verarbeitet und das Ergebnis als JSON zurückgibt.



// main.gopackage main

import ( "encoding/json" "syscall/js")

type InputData struct { Name string `json:"name"` Value float64 `json:"value"`}

type OutputData struct { Greeting string `json:"greeting"` Square float64 `json:"square"`}

func processData(this js.Value, args []js.Value) interface{} { if len(args) < 1 { return "Error: expected JSON string" } inputJSON := args[0].String()

var input InputData if err := json.Unmarshal([]byte(inputJSON), &input); err != nil { return "Error: " + err.Error() }

output := OutputData{ Greeting: "Hello, " + input.Name, Square: input.Value * input.Value, }

resultJSON, _ := json.Marshal(output) return string(resultJSON)}

func main() { c := make(chan struct{}, 0) js.Global().Set("processData", js.FuncOf(processData)) <-c}


Direkte Arbeit mit dem Speicher (binäres Protokoll)

Für maximale Leistung können Sie Daten über den linearen WASM-Speicher übertragen. Sie exportieren Funktionen zum Schreiben/Lesen aus dem Speicher und übergeben Zeiger (als ganze Zahlen) an JavaScript. Diese Methode ist komplexer, vermeidet aber den Overhead des JSON-Parsings.



// Export einer Funktion zum Schreiben in den Speicher//go:wasmexport allocateMemoryfunc allocateMemory(size int) uintptr {    // Verwenden Sie C.malloc oder einen eigenen Allokator    // Geben Sie einen Zeiger zurück}

//go:wasmexport getMemoryBufferfunc getMemoryBuffer() uintptr { // Geben Sie den Anfang des Puffers zurück}


In JavaScript verwenden Sie WebAssembly.Memory und Uint8Array zum Lesen/Schreiben an den erhaltenen Adressen.



2. Aufruf von JavaScript aus Go und DOM-Manipulation



Das Paket syscall/js ermöglicht es, beliebige JavaScript-Funktionen aufzurufen und das DOM zu manipulieren. Die fortgeschrittene Ebene umfasst die Erstellung reaktiver Oberflächen und die Ereignisbehandlung.



Erstellen und Aktualisieren von DOM-Elementen

func appendDiv(this js.Value, args []js.Value) interface{} {    document := js.Global().Get("document")    body := document.Get("body")

newDiv := document.Call("createElement", "div") newDiv.Set("innerHTML", "<h2>Hello from Go WASM!</h2>") newDiv.Get("style").Set("color", "blue") body.Call("appendChild", newDiv) return nil}

func main() { js.Global().Set("appendDiv", js.FuncOf(appendDiv)) select {}}


Ereignisbehandlung auf der Go-Seite

func setupClickHandler(this js.Value, args []js.Value) interface{} {    document := js.Global().Get("document")    button := document.Call("getElementById", "myButton")

clickCallback := js.FuncOf(func(this js.Value, args []js

Blogs

Buchempfehlungen