Go 和 WebAssembly: 在浏览器中运行 Go 程序

时间:2019-09-17 来源:www.mdjtour.com

去语言中文网,致力于每天分享代码,开源等知识,欢迎关注我,会有意想不到的收获!

昨晚发布的微型标题引发了激烈的讨论:

所以,热,让我们来看一篇关于Go和ism的文章。

长期以来,Javascript一直是Web开发人员的常用语言。如果你想编写一个稳定,成熟的Web应用程序,那么使用Javascript几乎是唯一的方法。

WebAssembly(也称为wasm)即将改变这种情况。使用WebAssembly,您现在可以使用任何语言编写Web应用程序。在本文中,我们将看到如何编写Go程序并使用wasm在浏览器中运行它们。

WebAssembly官方网站webassembly.org将其定义为“基于基于堆栈的二进制指令格式的虚拟机”。这是一个很好的定义,但让我们把它分解成我们能理解的东西。

从本质上讲,wasm是一种二进制格式,就像ELF,Mach和PE一样。唯一的区别是它适用于虚拟编译目标,而不是真正的物理机器。为什么是虚拟机?因为它与C/C ++二进制文件不同,所以wasm二进制文件并不特定于特定平台。因此,您可以在Linux,Windows和Mac上使用相同的二进制文件而无需进行任何更改。但是,我们需要一个额外的“代理”,它将wasm指令中的二进制文件转换为特定于平台的指令并运行它们。通常,这个“代理”是一个Web浏览器,但理论上它可以是其他任何东西。

这为我们提供了一个通用的编译目标,我们可以使用我们选择的任何编程语言构建Web应用程序。只要我们将程序编译成wasm格式,我们就不必担心目标平台了。就像我们编写Web应用程序一样,但现在我们可以用我们选择的任何语言编写它。

让我们尝试编写一个简单的“hello world”程序。确保您的Go版本至少为1.11。我们可以这样写:

保存为test.go文件。这似乎是一个常规的Go程序。现在让我们将这个文件编译成wasm平台。我们需要设置GOOS和GOARCH来编译它。

$ GOOS=js GOARCH=wasm Go build -o test.wasm test.go

我们现在已经生成了wasm二进制文件。但与本机系统不同,我们需要在浏览器中运行它。为此,我们需要投入额外的资金来实现这一目标:

将为我们的Web应用程序提供服务的Web服务器。一个index.html文件,包含用于加载wasm二进制文件的JS代码。一个JS文件,用作浏览器和我们的ism二进制文件之间的通信接口。

我喜欢把它想象成飞行女警女所需要的东西。

然后BOOM,我们有一个WebAssembly应用程序!

我们在Go版本中提供了HTML和JS文件,我们将在这里复制它们。

Serve是一个简单的Go二进制文件,它为当前目录中的所有文件提供服务。但几乎所有的Web服务器都这样做。

一旦我们运行它并打开我们的浏览器。我们看到一个Run按钮并单击它以执行我们的应用程序。然后我们点击它并检查控制台:

美丽!我们刚刚使用Go编写了一个程序并在浏览器中运行它。

到目前为止,它仍然相当不错。但这是一个简单的“你好世界”计划。真实的Web应用程序需要与DOM交互。我们需要响应按钮单击事件,从文本框中获取数据,并将数据发送回DOM。现在我们将构建一个使用所有这些功能的最小图像编辑器。

首先,为了使Go代码与浏览器交互,我们需要一个DOM API。我们需要syscall/js库来帮助我们解决这个问题。它是我们构建应用程序的一个非常基本但功能强大的DOM API。在我们继续制作应用程序之前,让我们快速浏览一下它的一些功能。

为了响应DOM事件,我们声明了回调并将它们与这些事件连接起来:

要从Go中更新DOM,我们可以这样做 -

您甚至可以像FileReader或Canvas一样调用JS函数并操作本机本机JS对象。请随时查看syscall/js文档以获取更多详细信息。

好的,现在开始构建我们的应用!

我们将构建一个小应用程序,它将接受图像输入,然后对图像执行操作,例如亮度,对比度,色调,饱和度,最后将图像输出回浏览器。每个效果都将使用滑块,用户可以更改这些效果并实时查看目标图像中的更改。

首先,我们需要将浏览器中的输入图像输入到Go代码中,以便我们可以处理它。为了有效地做到这一点,我们需要采取一些不安全的技巧并跳过细节。一旦我们拥有了图像,它就完全在我们的控制之下,我们可以做任何我们想做的事情。这是图像加载器回调的简短片段,为了简洁而略微优化:

然后我们从任何效果滑块中获取用户的值并操纵图像。我们使用伟大的bild库。这是操作对比回调的一小部分:

之后,我们将图像编码为jpeg格式并将其发送回浏览器。这是完整的应用程序操作:

我们加载图片:

改变对比度:

改变色调:

太棒了,我们可以在浏览器中本地操作图像,而无需编写一行Javascript代码!源代码可以在找到。

请注意,所有这些都是在浏览器中完成的。没有Flash插件,JavaApplet或Silverlight。开箱即用的浏览器本身为WebAssembly提供支持。

我的一些总结性发言:

由于Go是一种垃圾收集语言,因此整个运行周期都是wasm二进制文件。因此,这些二进制文件通常具有MB级别。与C/Rust语言相比,这是一个痛点;将MB级数据发送到浏览器并不理想。但是,如果wasm规范本身支持GC,那么这可能会改变。 Go中对ism的支持正在接受测试。 syscall/js API本身在不断变化,并将随之改变。如果您发现错误,请在我们的issue tracker上提出问题。像所有剧集一样,WebAssembly不是一个灵丹妙药。有时简单的JS更快更容易编写。然而,ism本身正在开发中并将引入更多功能。线程支持就是这样一个功能。

希望本文展示WebAssembly的一些很酷的方面,以及如何使用Go编写功能齐全的Web应用程序。如果您发现了错误,请尝试修复它并提出问题。如果您需要任何帮助,请随时访问#webassembly频道。

通过:

作者:Agniva De Sarker译者:PotoYang校对:polaris1119

本文最初由GCTT编制,Go语言中文网站很荣幸推出

——