使用go编写webassembly


使用go编写webassembly

使用go编写webassembly

webassembly是什么?

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

webassembly是可以支持在web浏览器或者v8等环境下的二进制格式,想具体了解可以查看这个回答

本文只介绍如何使用golang生成wasm文件,并在浏览器上执行。

编写需要编译成wasm文件的go文件

// main.go

package main
func main() {
    println("Hello, WebAssembly!")
}

执行build命令

GOARCH=wasm GOOS=js go build -o test.wasm main.go

注意这个是在mac或者linux操作系统下执行的命令,在windows下应该设置环境变量再执行编译命令

$env:GOARCH="wasm";$env:GOOS="js";

go build -o test.wasm main.go

命令执行完后,后生成test.wasm文件,这个就是可以在浏览器上运行的二进制文件

添加其他依赖

复制$(go env GOROOT)/misc/wasm/下的wasm_exec.html和wasm_exec.js两个文件到当前目录

搭建web服务器

// test.go

package main
import (
    "flag"
    "log"
    "net/http"
    "strings"
)
var (
    listen = flag.String("listen", ":8080", "listen address")
    dir    = flag.String("dir", ".", "directory to serve")
)
func main() {
    flag.Parse()
    log.Printf("listening on %q...", *listen)
    log.Fatal(http.ListenAndServe(*listen, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
        if strings.HasSuffix(req.URL.Path, ".wasm") {
            resp.Header().Set("content-type", "application/wasm")
        }
        http.FileServer(http.Dir(*dir)).ServeHTTP(resp, req)
    })))
}

运行web服务

go run test.go

测试

在浏览器中打开http://localhost:8080/wasm_exec.html,点击页面中的run按钮,即可看到控制台打印Hello, WebAssembly!

这样我们就已经可以使用go编写一个可以运行在浏览器的程序了

如何使用js

使用go的js库syscall/js

// main.go

package main
import (
   "fmt"
   "syscall/js"
)
func sayHi(value js.Value, args []js.Value) interface{} {
   fmt.Println("Hi!")
   return nil
}
func sayHello(value js.Value, args []js.Value) interface{} {
   callback := args[len(args)-1:][0]
   message := args[0].String()
   callback.Invoke(js.Null(), "Did you say "+message)
   return nil
}
func registerCallbacks() {
   js.Global().Set("sayHi", js.FuncOf(sayHi))
   js.Global().Set("sayHello", js.FuncOf(sayHello))
}
func main() {
   c := make(chan struct{}, 0)
   registerCallbacks()
   <-c
}
Last Updated:
Contributors: 刘荣杰