如何使用WebAssembly在浏览器中运行Go?

如果熟悉Go  Playground,那么就会知道在浏览器中安装Go暂存器有多方便。想给别人看一段代码片段吗?是否想快速测试一些语法?基于浏览器的代码垫很有帮助。关于这一点,我创建了一个新的游乐场。关于这个新游乐场的妙处在于,它不使用远程服务器来运行代码,而只是用于对其进行编译。该代码在您的浏览器中使用Web  Assembly运行。

如何使用WebAssembly在浏览器中运行Go?_业界动态_数字化

 它是如何工作的?

当用户单击“运行”时,代码将发送回我们的服务器。服务器是用Go语言编写的。因此,API的处理程序如下所示:

func compileCodeHandler(w http.ResponseWriter, r *http.Request) {

defer r.Body.Close()

// Get code from params

type parameters struct {

Code string

}

decoder := json.NewDecoder(r.Body)

params := parameters{}

err := decoder.Decode(¶ms)

if err != nil {

respondWithError(w, 500, "Couldn't decode parameters")

return

}

// create file system location for compilation path

usr, err := user.Current()

if err != nil {

respondWithError(w, 500, "Couldn't get system user")

return

}

workingDir := filepath.Join(usr.HomeDir, ".wasm", uuid.New().String())

err = os.MkdirAll(workingDir, os.ModePerm)

if err != nil {

respondWithError(w, 500, "Couldn't create directory for compilation")

return

}

defer func() {

err = os.RemoveAll(workingDir)

if err != nil {

respondWithError(w, 500, "Couldn't clean up code from compilation")

return

}

}()

f, err := os.Create(filepath.Join(workingDir, "main.go"))

if err != nil {

respondWithError(w, 500, "Couldn't create code file for compilation")

return

}

defer f.Close()

dat := []byte(params.Code)

_, err = f.Write(dat)

if err != nil {

respondWithError(w, 500, "Couldn't write code to file for compilation")

return

}

// compile the wasm

const outputBinary = "main.wasm"

os.Setenv("GOOS", "js")

os.Setenv("GOARCH", "wasm")

cmd := exec.Command("go", "build", "-o", outputBinary)

cmd.Dir = workingDir

stderr, err := cmd.StderrPipe()

if err != nil {

respondWithError(w, 500, err.Error())

return

}

if err := cmd.Start(); err != nil {

respondWithError(w, 500, err.Error())

return

}

stdErr, err := ioutil.ReadAll(stderr)

if err != nil {

respondWithError(w, 500, err.Error())

return

}

stdErrString := string(stdErr)

if stdErrString != "" {

parts := strings.Split(stdErrString, workingDir)

if len(parts) < 2 {

respondWithError(w, 500, stdErrString)

return

}

respondWithError(w, 400, parts[1])

return

}

if err := cmd.Wait(); err != nil {

respondWithError(w, 500, err.Error())

return

}

// write wasm binary to response

dat, err = ioutil.ReadFile(filepath.Join(workingDir, outputBinary))

if err != nil {

respondWithError(w, 500, err.Error())

return

}

w.Write(dat)

}

如您所见,处理程序仅将代码作为输入,并以WASM字节片作为响应。

 前端呢?

前端非常简单。首先,我们需要在页面中包括Go WASM的官方执行者。假设您的计算机上已安装Go,可以在以下位置找到此JavaScript文件:

$(go env GOROOT)/misc/wasm/wasm_exec.js

然后在您的html正文中包含脚本:

<!DOCTYPE html>
<html>
<head>
<title>Qvault Classroom - Learn Coding</title>
</head>
<body>
<script  src="wasm_exec.js"></script>
</body>
</html>


因为Qvault  Classroom的前端是作为Vue.js单页应用程序编写的,所以我创建了一个小的es6模块,该模块运行WASM字节数组并将输出作为行数组返回:

const go = new window.Go();export default async function runGoWasm(rawData)  {

const result = await WebAssembly.instantiate(rawData, go.importObject);

let oldLog = console.log;

let stdOut = [];

console.log = (line) => {stdOut.push(line);};

await go.run(result.instance);

console.log = oldLog;

return stdOut;

}

关于如何使用Web Assembly在浏览器中运行Go 的内容,介绍到这里就结束了。如果还想了解更多关于Web  Assembly的信息,请继续关注。

52
111
0
22

相关资讯

  1. 1、《主流》曝美版海报导演为弗朗西斯·科波拉孙女2458
  2. 2、赵丽颖再接古装片,男一号是全网喜欢大叔,该剧看颜值还是演技?4511
  3. 3、《长安伏妖》汇聚超级无厘头班底和金牌主创阵容,开启贺岁档序幕2428
  4. 4、半妖司藤讲了什么司藤秦放小说结局大虐观众泪奔932
  5. 5、内地票房:《北爱》2亿夺冠《大闹天宫》近10亿3195
  6. 6、豆瓣9.1的神片,只用5天就从《海王》口中抢下1.04亿票房1110
  7. 7、她是杨不悔,也是余英男,古装扮相清新软萌!2522
  8. 8、《风云》雄霸的师父,绝无神的师父,帝释天的师父,差距一目了然1617
  9. 9、河正宇联合《恐怖直播》导演强势回归新动作片下月上映2209
  10. 10、《细思极恐》惊悚上映获赞吓点密集1144
全部评论(0)
我也有话说
0
收藏
点赞
顶部