wasm That webAssemble, which is not a binary format file for a particular platform. Go from 1.11 begun to support wasm, initially by js.NewCallBack () function is registered, 1.12 start into a FuncOf ().
Go wasm need to develop a go file for writing implementation code, compiled into .wasm file; wasm_exec.js need a file, this is provided by Go, Go can be found in the misc subdirectory of the installation directory where it will be directly copied. It implements and WebAssembly module interaction function; another is the need for an HTML file for loading wasm file. Of course, in order to work together, we need to implement a simple HTTP service.
First, write code with Go and compiled into wasm file
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package main 2 3 import ( 4 "fmt" 5 "math/rand" 6 "strconv" 7 "syscall/js" 8 "time" 9 ) 10 11 const ( 12 width = 400 13 height = 400 14 ) 15 16 // 生成 0 - 1 的随机数 17 func getRandomNum() float32 { 18 rand.New (. rand.NewSource (Time.now () UnixNano ())) . 19 n-: = float32 (rand.Intn ( 10000 )) 20 is return n-/ 10000.0 21 is } 22 is 23 is // generates a 0 - 10 of the random number 24 FUNC getRandomNum2 () {float32 25 rand.New (. rand.NewSource (Time.now () UnixNano ())) 26 is n-: = float32 (rand.Intn ( 10000 )) 27 return n-/ 1000.0 28 } 29 30 / / use drawing canvas random FIG. 31 is FUNC draw () { 32 var canvas = js.Value js. 33 Global(). 34 Get("document"). 35 Call("getElementById", "canvas") 36 37 var context js.Value = canvas.Call("getContext", "2d") 38 39 // reset 40 canvas.Set("height", height) 41 canvas.Set("width", width) 42 is context.Call ( " the clearRect " , 0 , 0 , width, height) 43 is 44 is // random straight line drawn 50 45 var clineStyle = `RGBA (% D,% D, D%, 0.5 )` 46 is for I: = 0 ; I < 50 ; I ++ { 47 the lineStyle: = fmt.Sprintf (clineStyle, 155 + int (getRandomNum2 () * 10 ), 155 + int (getRandomNum () * 100 ), 155 + int(getRandomNum()*100)) 48 fmt.Println(lineStyle) 49 context.Call("beginPath") 50 context.Set("strokeStyle", lineStyle) 51 context.Call("moveTo", getRandomNum()*width, getRandomNum()*height) 52 context.Call("lineTo", getRandomNum()*width, getRandomNum()*height) 53 context.Call("stroke") 54 } 55 56 context.Set("font", "30px Arial") 57 context.Set("strokeStyle", "blue") 58 for i := 0; i < 10; i++ { 59 context.Call("strokeText", "hello wasm", (getRandomNum2()+1)*10+getRandomNum2()*10,(getRandomNum2 () + 10) *1+getRandomNum2()*50) 60 } 61 } 62 63 func registerCallbackFunc() { 64 cb := js.FuncOf(func(this js.Value, args []js.Value) interface{} { 65 fmt.Println("button clicked") 66 67 num1 := getElementByID("num1").Get("value").String() 68 v1, err := strconv.Atoi(num1) 69 if nil != err { 70 fmt.Println("button clicked:", num1, err.Error()) 71 jsAlert().Invoke(err.Error()) 72 // panic(err) 73 return nil 74 } 75 76 num2 := getElementByID("num2").Get("value").String() 77 v2, err := strconv.Atoi(num2) 78 if nil != err { 79 fmt.Println("button clicked:", num2, err.Error()) 80 // panic(err) 81 return nil 82 } 83 84 rlt := v1 + v2 85 getElementByID("rlt").Set("value", rlt) 86 87 return nil 88 }) 89 90 getElementByID("compute").Call("addEventListener", "click", cb) 91 } 92 93getElementByID FUNC (ID String ) js.Value { 94 return js.Global (). the Get ( " Document " ) .CALL ( " the getElementById " , ID) 95 } 96 97 FUNC jsAlert () js.Value { 98 return js.Global () .Get ( " Alert " ) 99 } 100 101 FUNC main () { 102 fmt.Println ( " the Hello, webassembly Go! " ) 103 Draw () 104 // by js.Global (). get () to get refers to the global alert function 105 alert:. = Js.Global () the Get ( " alert " ) 106 // call to call alert function alert.Invoke 107 alert.Invoke ( " Hello World " ) 108 109 registerCallbackFunc () 110 }
The code is compiled into Wasm file, you need to set the compiler environment. I use VsCode, can not always take effect with powershell set environment variables, then replaced Bash:
Execution: go env viewing environment, pay attention to GOOS and GOARCH, if the system is to win, then, should be the default windows and amd64, to compile wasm files need to be modified as follows:
export GOOS=js
export GOARCH=wasm
Otherwise, you will be prompted strange compile time information (instead of prompting environmental issues), or if not, you can set CGO:
export CGO_ENABLED=0
Of course, I set 1 is not the problem.
Finally compiled wasm file:
go build -o lib.wasm main.go
-o parameter is the compiler, specify the output file.
Go in there to introduce: syscall / js
). The Get () Gets js object via js.Global (, both functions can be acquired, may be acquired DOM elements. Type is js.Value.
Such as:
If a property element is set to call Set (), if the call is (execution) method, call Call ( "function name", "Parameters").
Such as:
Second, write HTML
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <script src="wasm_exec.js"></script> 5 <script> 6 const go = new Go(); 7 WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then((result) => { 8 go.run(result.instance); 9 }); 10 </script> 11 </head> 12 <body> 13 <canvas id='canvas'></canvas></br> 14 <input id="num1" type="number" /> 15 + 16 <input id="num2" type="number" /> 17 = 18 <input id="rlt" type="number" readonly="readonly" /> 19 <button id="compute">compute</button> 20 </body> 21 </html>
HTML file is the definition of interface elements introduced wasm_exec.js file, call just build the lib.wasm.
Third, write an HTTP service
Go built-in HTTP server supports Content-Type is application / wasm.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package main 2 3 import ( 4 "flag" 5 "log" 6 "net/http" 7 ) 8 9 var ( 10 listen = flag.String("listen", ":8087", "listen address") 11 dir = flag.String("dir", ".", "files directory to serve") 12 ) 13 14 func main() { 15 flag.Parse() 16 log.Printf("listening on %q...", *listen) 17 err := http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir))) 18 log.Fatalln(err) 19 }
Here we must note: In order to compile wasm file before modifying the GOOS and GOARCH, now in order to run the http service, we must restore.
To facilitate debugging, we can create a new terminal in vscode inside, execute:
export GOOS=windows
export GOARCH=amd64
Then execute:
go run server.go
If there is a firewall prompt network access, select Allow, and then see the terminal prompt:
2020/03/10 09:27:12 listening on ":8087"...
This means that our HTTP service started well.
Fourth, the test results
Enter in the browser: http: //127.0.0.1: 8087 /
You can see the page pops up a dialog box:
Then came what we draw:
See the output content in a browser debugger inside:
There is also a page of function calculation, we enter a number, click the button, found no response, see the debugger can see the error:
Prompt information is clear, look at our Go back to the code, main () function in the implementation of the registerCallbackFunc () on the end of the exit,
This time again certainly fail to call, so we can not let the program exits:
. 1 FUNC main () { 2 fmt.Println ( " ! The Hello, webassembly Go " ) . 3 Draw () . 4 // reference to get a global alert function by js.Global () the Get (). . 5 alert: = js.Global () .Get ( " alert " ) . 6 // call to call alert function alert.Invoke . 7 alert.Invoke ( " Hello World " ) . 8 DONE: = the make (Chan struct {}, 0 ) // Create unbuffered channel 9 10 registerCallbackFunc () . 11 <-done // blocked 12 }
Creating a channel on line 8, and then read content from 11 channels in line, because the channel has no content, it will be blocked.
Then recompile wasm file, refresh the page, you can see the expected reach:
This is the basic routines developed by Go Wasm of the.