精华内容
下载资源
问答
  • wasm_game_of_life Conway 在 Rust 和 WebAssembly 中的生命游戏 | 内置 :crab: :spider_web: 作者 关于 该存储库包含 Rust 和 WebAssembly 教程的完整代码。 本教程构建了越来越多的实现。
  • WebAssembly 入门教程

    2021-10-11 10:28:37
    什么是 WebAssembly?在其主页上:https://webassembly.org/ 有如下描述: WebAssembly(缩写为 Wasm)是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm 被设计为用于编译编程语言的可移植目标,支持在 Web 上...

    简介

    什么是 WebAssembly?在其主页上:https://webassembly.org/ 有如下描述:

    WebAssembly(缩写为 Wasm)是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm 被设计为用于编译编程语言的可移植目标,支持在 Web 上部署客户端和服务器应用程序。

    目前 Rust 对 WebAssembly 的支持较好。那 Go 什么时候开始支持支持 WebAssembly 的呢?

    Go 1.11 向 WebAssembly 添加了一个实验性端口。Go 1.12 对其某些部分进行了改进,Go 1.13 有了进一步改进。

    入门示例

    首先,请保证安装了 Go1.11 以上版本,建议安装最新版本 Go。

    在本地创建一个项目:gowasm(Windows 用户自行修改路径)

    $ mkdir ~/gowasm
    $ cd ~/gowasm
    $ go mod init gowasm
    $ touch main.go
    

    要为 Web 编译基本的 Go 包,打开 main.go,填上如下代码:

    package main
    
    import "fmt"
    
    func main() {
     fmt.Println("Hello, WebAssembly!")
    }
    

    为 WebAssembly 编译设置GOOS=js和GOARCH=wasm环境变量:

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

    这将构建包并生成一个名为 main.wasm 的可执行 WebAssembly 模块文件。.wasm 文件扩展名使得通过 HTTP 用正确的 Content-Type 标头来更好地提供它。

    请注意,你只能编译 main 包。否则,你将获得一个无法在 WebAssembly 中运行的目标文件。如果你有一个包希望能够与 WebAssembly 一起使用,请将其转换为 main 包并构建它得到一个二进制文件。

    要在浏览器中执行 main.wasm,我们还需要一个 JavaScript 支持文件和一个 HTML 页面来将所有内容连接在一起。

    复制 JavaScript 支持文件:

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

    创建一个index.html文件:

    <html>
     <head>
      <meta charset="utf-8"/>
      <script src="wasm_exec.js"></script>
      <script>
       const go = new Go();
       WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
        go.run(result.instance);
       });
      </script>
     </head>
     <body></body>
    </html>
    

    如果你的浏览器尚不支持WebAssembly.instantiateStreaming,可以使用 polyfill。

    然后从 Web 服务器服务这三个文件(index.html、wasm_exec.js和 main.wasm)。例如,使用 goexec。注意,安装 goexec 后,放入 PATH 目录,方便使用:

    # 先安装 goexec
    $ go install github.com/shurcooL/goexec@latest
    # 执行 goexec(如果提示你缺少 github.com/shurcooL/go-goon,请 go get 下载)
    $ goexec 'http.ListenAndServe(`:8080`, http.FileServer(http.Dir(`.`)))'
    

    当然也可以使用任何其他的方式提供 HTTP 服务。

    打开浏览器访问 http://localhost:8080/index.html,打开 JavaScript 调试控制台(Console Tab),你应该会看到输出:Hello, WebAssembly!

    你可以修改程序、重新编译 main.wasm,刷新以查看新输出。(goexec 不需要重启)

    总结

    Go 的安全更新,如果涉及到你的项目,建议升级,否则可以不升级。WebAssembly 这两年挺火的,但生产使用还是很少。有兴趣可以学习了解。本文希望能够带给你一个初步印象。

    展开全文
  • webassembly_tutorial.pdf

    2020-08-19 16:32:30
    webassembly 开发的手册,如何结合C++,python,node.js, Rust前后端数据传输。内容包括安装及编译工具,语法规则及实例
  • 在上一篇文章里,我们介绍了学习 WebAssembly 的常见问题。 现在先从 Rust 开始动手实践吧。 Rust 是当今编写 WebAssembly 应用程序的最佳语言。 本文所用到的源代码Repo请点击:...

    在上一篇文章里,我们介绍了学习 WebAssembly 的常见问题

    现在先从 Rust 开始动手实践吧。 Rust 是当今编写 WebAssembly 应用程序的最佳语言。

    本文所用到的源代码Repo请点击:https://github.com/second-state/wasm-learning/tree/master/rust

    虽然 WebAssembly 支持多种编程语言,但迄今为止, Rust 拥有最好的工具。 在过去的4年里,Rust 被 StackOverflow 用户评选为最受喜爱的编程语言,是增长最快的编程语言之一。

    Rust 像 C 一样通用和高效,但是由于它的编译器设计,Rust 比 C 安全得多。 像 C 语言一样,Rust 有一个学习曲线。 在本教程中,我将帮助您开始使用 Rust 编程语言。你可以通过在线资源,比如这本书了解更多有关 Rust 语言的信息。

    安装Rust

    在典型的 Linux 系统里,运行下面的指令安装 Rust 编译器和 cargo工具来创建管理。

    $ sudo apt-get update
    $ sudo apt-get -y upgrade
    
    $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    $ source $HOME/.cargo/env
    

    Hello World

    此演示应用程序的源代码可以点击:https://github.com/second-state/wasm-learning/blob/master/rust/hello.md

    首先,让我们使用 cargo 创建一个新项目。

    $ cargo new hello
         Created binary (application) `hello` package
    $ cd hello
    

    src/main.rs 中的main () 函数,是执行 Rust 应用程序时的入口点。Src / main. Rs 文件内容如下。该代码只是将一个字符串“ helloworld”打印到标准输出。

    fn main() {
      println!(“Hello, world!”);
    }
    

    接下来为你的机器创建二进制可执行文件。

    $ cargo build --release
       Compiling hello v0.1.0 (/home/ubuntu/wasm-learning/rust/hello)
        Finished release [optimized] target(s) in 0.22s
    

    你现在可以运行你的第一个 Rust 程序并查看 console 上的“Hello World”

    $ target/release/hello
    Hello, world!
    

    互动

    这个演示的源代码可以在这里找到 https://github.com/second-state/wasm-learning/blob/master/rust/cli.md。

    同样,让我们使用 cargo 创建一个新项目。

    $ cargo new cli
         Created binary (application) `cli` package
    $ cd cli
    

    Src / main.Rs 文件的内容如下。env::args() 会保存我们执行程序时从命令行传递的字符串值。 这里还要注意到,我们先创建一个 Rust 字符串,然后将更多的字符串引用附加给它。 为什么我们必须连接字符串引用而不是字符串值? 这就是 Rust 让程序变得安全的原因。 点击这里了解更多。

    use std::env;
    
    fn main() {
        let args: Vec<String> = env::args().collect();
        println!("{}", String::from("Hello ") + &args[1]);
    }
    

    接下来,为你的机器创建二维码可执行文件。

    $ cargo build --release
    

    你可以运行程序,并传入一段命令行代码

    $ target/release/cli Rust
    Hello Rust
    

    WebAssembly 呢?

    现在我们已经了解了如何从 Rust 源代码创建本地可执行的程序。 可执行的程序只能在生成计算机上运行,可能不安全。 在接下来的教程中,将展示:

    • 如何从 Rust 源代码构建 WebAssembly 字节码程序而不是本地可执行文件。
    • 如何通过 web 浏览器而不是繁琐的命令行与 WebAssembly 程序进行交互。

    相关阅读

    展开全文
  • 在 Rust 中创建一个简单的 WebAssembly 应用程序,然后从 JavaScript 调用这个程序 本文所涉及的所有代码可以在 https://github.com/second-state/wasm-learning/tree/master/browser/triple 中找到。 系列教程 ...

    在 Rust 中创建一个简单的 WebAssembly 应用程序,然后从 JavaScript 调用这个程序

    本文所涉及的所有代码可以在 https://github.com/second-state/wasm-learning/tree/master/browser/triple 中找到。

    WebAssembly 入门教程
    系列教程

    1. WebAssembly 快问快答
    2. Rust 的 Hello world

    在本教程中,我们将创建一个非常简单但很完整的 WebAssembly 应用程序。

    Webassembly 应用程序通常由两部分组成。

    • 运行在 WebAssembly 虚拟机内部以执行计算任务的字节码程序

    • 提供 UI、networking、数据库,以及调用 WebAssembly 程序以执行关键计算任务或业务逻辑的主机应用程序

    在本教程中,主机应用程序是用 JavaScript 编写的,并在 web 浏览器中运行。 Webassembly 字节码程序是用 Rust 编写的。

    现在,先让我们看看 Rust 程序是如何编写的。

    在 Rust 中的 WebAssembly 程序

    在这个例子中,Rust 程序将输入数字简单地增加了三倍并返回结果。 首先将 WebAssembly 工具安装到 Rust 编译器。

    # Install Rust
    
    $ sudo apt-get update
    $ sudo apt-get -y upgrade
    $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    $ source $HOME/.cargo/env
    
    # Install WebAssembly tools
    
    $ rustup target add wasm32-wasi
    $ rustup override set nightly
    $ rustup target add wasm32-wasi --toolchain nightly
    

    接下来,创建一个新的 cargo 项目。
    由于这个程序是从主机应用程序调用的,而不是作为独立的可执行文件运行,因此我们将创建一个 lib 项目。

    $ cargo new --lib triple
    $ cd triple
    

    编辑 Cargo.toml 文件以添加[lib]节。 它会告诉编译器在哪里可以找到库的源代码,以及如何生成字节码输出。

    [lib]
    name = "triple_lib"
    path = "src/lib.rs"
    crate-type =["cdylib"]
    

    下面是 Rust 程序 src/lib.rs 的内容. 实际上,你可以在这个库文件中定义多个外部函数,并且所有这些函数都可以通过 WebAssembly 在 JaveScript 主机上使用。

    #[no_mangle]
    pub extern fn triple(x: i32) -> i32 {
      return 3 * x;
    }
    

    接下来你可以用下面的命令行编译 Rust 的源代码到WebAssembly的字节码中。

    $ cargo +nightly build --target wasm32-wasi --release
    

    WebAssembly 字节码文件是 target/wasm32-wasi/release/triple_lib.wasm

    JavaScript 主机

    我们使用 JavaScript 加载 WebAssembly 字节码程序并调用它的函数。 由于大多数浏览器已经支持 WebAssembly, JavaScript 实际上可以作为一个网页运行。

    无须赘述,下面是 JavaScript 模块的相关部分,用于加载、导出和调用 WebAssembly 函数。 完整的网页源文件在这里

    <script>
      if (!('WebAssembly' in window)) {
        alert('you need a browser with wasm support enabled :(');
      }
      (async () => {
          const response = await fetch('triple_lib.wasm');
          const buffer = await response.arrayBuffer();
          const module = await WebAssembly.compile(buffer);
          const instance = await WebAssembly.instantiate(module);
          const exports = instance.exports;
          const triple = exports.triple;
          
          var buttonOne = document.getElementById('buttonOne');
          buttonOne.value = 'Triple the number';
          buttonOne.addEventListener('click', function() {
            var input = $("#numberInput").val();
            alert(input + ' tripled equals ' + triple(input));
          }, false);
      })();
    </script>
    
    

    可以看到 JavaScript 代码加载了 WebAssembly 虚拟机的 triple_lib.wasm 文件, 导出其外部函数,然后根据需要调用这些函数。

    将这个 HTML 文件和 triple_lib.wasm 文件放在web 服务器上,你就可以访问网页,在网页上输入的任何数字会自动乘以三。

    那么字符串呢

    现在你注意到了,这个例子并不是一个 hello world。 WebAssembly函数计算数字,但不会像 hello world 那样操作字符串。

    这是为什么呢? 我们将在下一个教程中回答这个问题,并给出一个真实的 hello world 示例。

    展开全文
  • 欢迎来到WebAssembly教程系列的第一篇。 WebAssembly是什么? JavaScript已成为浏览器可以理解的唯一语言。它经历了时间的考验,可以满足大多数web应用的性能需求。但是,当遇到3D游戏、VR、AR以及图像编辑等应用...

    原文:https://golangbot.com/webassembly-using-go/

    欢迎来到WebAssembly教程系列的第一篇。

    WebAssembly是什么?

    JavaScript已成为浏览器可以理解的唯一语言。它经历了时间的考验,可以满足大多数web应用的性能需求。但是,当遇到3D游戏、VR、AR以及图像编辑等应用的时候,JavaScript就不那么好用了,其原因是它是一种解释性的语言。虽然像Gecko和V8这样的JavaScript引擎已具备JIT特性,但JavaScript还是不能完全满足现代web应用所需的高性能。

    WebAssembly(又称wasm)的目标就是解决这个问题。它是一种专为浏览器设计的虚拟汇编语言。所谓虚拟,意思就是它不能直接运行于底层的硬件之上。因为浏览器可能运行在任意体系的硬件上,所以浏览器不可能让WebAssembly直接运行于底层硬件之上。但是,WebAssembly采用了高度优化的虚拟汇编格式,它在浏览器中运行时要比普通的JavaScript快得多,这是由于它是编译型的而且比JavaScript更靠近硬件体系。下图显示了WebAssembly与JavaScript在栈中的位置。它比JavaScript更靠近硬件一些。

    WebAssembly is closer to the hardware

    现有的JavaScript引擎基本上都可以支持WebAssembly虚拟汇编代码的运行。

    WebAssembly的目标并不是替代JavaScript。它的目标是与JavaScript一起配合,以实现web应用中性能敏感的部分。可以从JavaScript调用WebAssembly,反之亦然。

    WebAssembly通常并不需要手工编写汇编代码,而是从其它高级语言编译得到。例如,可以从Go、C、C++或Rust等代码编译得到WebAssembly。因此,在其它语言中已实现的模块也可以被编译成WebAssembly,从而在浏览器中直接使用。

    如何开发?

    在本教程中,我们将把一个Go程序编译为WebAssembly并在浏览器中运行它。

    我们将创建一个对JSON进行格式化的简单程序。如果输入的是一个未格式化的JSON串,我们把它格式化后再打印出来。

    例如,输入的JSON如下: 

    {"website":"golangbot.com", "tutorials": {"string":"https://golangbot.com/strings/", "maps":"https://golangbot.com/maps/", "goroutine":"https://golangbot.com/goroutines/", "channels":"https://golangbot.com/channels/"}}

    它会被格式化并在浏览器中显示以下内容:

    {
      "tutorials": {
        "channels": "https://golangbot.com/channels/",
        "goroutine": "https://golangbot.com/goroutines/",
        "maps": "https://golangbot.com/maps/",
        "string": "https://golangbot.com/strings/"
      },
      "website": "golangbot.com"
    }

     我们还会为这个应用创建一个UI,并在Go语言中操纵浏览器的DOM,不过这个要留到下一个教程。

    本教程代码在Go 1.13以上版本中测试通过。

    从Go编译WebAssembly的Hello World程序

    我们从编写一个Go的最简单的hello world程序开始,把它编译成WebAssembly并在浏览器上运行。然后我们再修改这个程序,把它变成我们的JSON格式化应用。

    我们先来创建以下目录结构,比如在Documents目录之下:

    Documents/  
    └── webassembly
        ├── assets
        └── cmd
            ├── server
            └── wasm

    后面将逐步明晰各个文件夹的用途。

    在~/Documents/webassembly/cmd/wasm目录下创建一个main.go文件,文件内容如下:

    package main
    
    import (  
        "fmt"
    )
    
    func main() {  
        fmt.Println("Go Web Assembly")
    }

    我们来把它编译成WebAssembly。以下命令将对这个Go程序进行编译并将输入的二进制文件存放在assets文件夹中:

    cd ~/Documents/webassembly/cmd/wasm/  
    GOOS=js GOARCH=wasm go build -o  ../../assets/json.wasm  

    以上命令使用js作为GOOS,wasm作为GOARCH,wasm是WebAssembly的缩写。执行这一命令将在assets目录下创建一个名为json.wasm的WebAssembly模块。恭喜!我们已经成功将第一个Go程序编译成WebAssembly了。

    有一个重要的提示就是,只能将main包编译成WebAssembly。所以我们必须把所有代码都写在main包中。

    如果你试图在终端上运行这个二进制文件,像这样:

    $]~/Documents/webassembly/assets/json.wasm 
    
    -bash: json.wasm: cannot execute binary file: Exec format error

    你将收到一个错误提示。这是因为这个二进制文件是一个wasm二进制文件,只能在浏览器沙盒中运行。Linux或Mac操作系统无法理解这种格式,所以提示错误。

    JavaScript胶水

    前面已提到过,WebAssembly是需要和JavaScript一起配合运行的。因些我们需要一些JavaScript胶水代码来引入我们刚才得到的WebAssembly模块,以便在浏览器中运行。这些胶水代码已存在于Go的安装路径下。我们只需要把它复制到我们的assets目录下即可:

    cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ~/Documents/webassembly/assets/ 

    以上命令将wasm_exec.js复制到assets目录下,这个js文件中包含了用于运行WebAssembly的胶水代码。

    现在你应该已知道,assets文件夹的用途就是用于存放我们的web服务器所要使用的所有HTML、JavaScript和wasm代码。

    Index.html

    现在我们已经准备好wasm二进制文件以及胶水代码了。下一步就是创建一个index.html文件用于导入我们的wasm文件。

    我们创建一下index.html文件,还是在assets目录下,文件内容如下。文件中包含了运行WebAssembly模块所需的样板代码,参看WebAssembly Wiki

    <html>  
        <head>
            <meta charset="utf-8"/>
            <script src="wasm_exec.js"></script>
            <script>
                const go = new Go();
                WebAssembly.instantiateStreaming(fetch("json.wasm"), go.importObject).then((result) => {
                    go.run(result.instance);
                });
            </script>
        </head>
        <body></body>
    </html> 

    创建index.html之后的目录结构如下:

    Documents/  
    └── webassembly
        ├── assets
        │   ├── index.html
        │   ├── json.wasm
        │   └── wasm_exec.js
        └── cmd
            ├── server
            └── wasm
                └── main.go

    虽然index.html只是一个标准的样板,但是稍微了解一下也无妨。我们来尝试了解一下index.html中的代码。instantiateStreaming函数是用来初始化我们的json.wasm模块。这个函数返回一个WebAssembly实例,实例中包含一个可以被JavaScript调用的WebAssembly函数列表。要从JavaScript中调用我们的wasm函数,这一步是必须的。随着教程的继续,它的用法会越来越清晰。

    Web服务器

    现在我们已经准备好了JavaScript胶水、index.html以及我们的wasm二进制文件。最后还缺少的一块就是,我们需要一个web服务器来提供assets文件夹中的这些内容。开干吧!

    在server目录下创建一个main.go文件,目录结构将变成:

    Documents/  
    └── webassembly
        ├── assets
        │   ├── index.html
        │   ├── json.wasm
        │   └── wasm_exec.js
        └── cmd
            ├── server
            |   └── main.go
            └── wasm
                └── main.go

    将以下代码输入~/Documents/webassembly/cmd/server/main.go:

    package main
    
    import (  
        "fmt"
        "net/http"
    )
    
    func main() {  
        err := http.ListenAndServe(":9090", http.FileServer(http.Dir("../../assets")))
        if err != nil {
            fmt.Println("Failed to start server", err)
            return
        }
    }

    以上程序创建一个文件服务器,在9090端口监听,以我们的assets文件夹作为根目录。这就是我们想要的。我们来运行这个服务器,看看我们第一个WebAssembly程序开始运行。

    cd ~/Documents/webassembly/cmd/server/  
    go run main.go 

    服务器监听于9090端口。启动你喜欢的浏览器,敲入http://localhost:9090。你会看到页面是空的。不要紧张,后面我们会创建UI的。

    现在我们要关注的是JavaScript控制台。在浏览器中右击鼠标并选择"检查"。 

    inspect WebAssembly

     

    开发者控制台将被打开。选择"控制台"页。

    developer console 你将看到控制台中有一段"Go Web Assembly"文字。漂亮!我们已经成功运行了我们的第一个用Go编写的WebAssembly程序。从Go编译生成的WebAssembly模块已被我们的服务器提供给到浏览器,并被浏览器的JavaScript引擎正确执行。

    下面我们再进一步,开始编写我们的JSON格式化器。

    编写JSON格式化器

    我们的JSON格式化器以未格式化的JSON作为输入,对其进行格式化,并返回格式化后的JSON字符串作为输出。我们可以用MarshalIndent函数来实现。 

    把以下函数加入到~/Documents/webassembly/cmd/wasm/main.go:

    func prettyJson(input string) (string, error) {  
        var raw interface{}
        if err := json.Unmarshal([]byte(input), &raw); err != nil {
            return "", err
        }
        pretty, err := json.MarshalIndent(raw, "", "  ")
        if err != nil {
            return "", err
        }
        return string(pretty), nil
    }

    MarshalIndent函数有3个输入参数。第一个是未格式化的JSON串,第二个是要加到每行JSON前的前缀。这里我们不需要加前缀。第三个参数是每行JSON的缩入要增加的字符串。这里我们给定两个空格。这样,格式化时每次JSON行要缩入,就会多增加两个空格。 

    如果把字符串 {"website":"golangbot.com", "tutorials": {"string":"https://golangbot.com/strings/"}} 作为输入传给以上函数,它将返回以下格式化JSON字符串:

    {
      "tutorials": {
        "string": "https://golangbot.com/strings/"
      },
      "website": "golangbot.com"
    }

    从Go暴露函数给JavaScript

    我们的函数已经准备好了,但是我们还没有把这个函数暴露给JavaScript以使得该函数可以从前端调用。

    Go提供了syscall/js包,可以帮助我们从Go把函数暴露给JavaScript。

    暴露函数给JavaScript的第一步是创建一个Func类型。Func是一个被包裹的Go函数,它可以被JavaScript调用。可以用FuncOf函数来创建Func类型。

    把以下函数加入到~/Documents/webassembly/cmd/wasm/main.go:

    func jsonWrapper() js.Func {  
            jsonFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
                    if len(args) != 1 {
                            return "Invalid no of arguments passed"
                    }
                    inputJSON := args[0].String()
                    fmt.Printf("input %s\n", inputJSON)
                    pretty, err := prettyJson(inputJSON)
                    if err != nil {
                            fmt.Printf("unable to convert to json %s\n", err)
                            return err.Error()
                    }
                    return pretty
            })
            return jsonFunc
    }

    FuncOf函数接受一个函数类型的参数,该类型的函数应带有两个参数以及一个interface{}返回类型。传递给FuncOf的函数将会被JavaScript以同步方式调用。这个函数的第一个参数是JavaScript的this关键字。this指向JavaScript的global对象。第二个参数是一个[]js.Value切片,表示被传入到这个JavaScript函数调用的所有参数。在这个例子中,应该只传入一个参数,即未格式化的JSON字符串。如果你觉得不太好理解也不要紧。程序完成的时候你会搞清楚的:)。

    我们首先检查传入的参数数量是否为1(第3行)。这个检查是需要的,因为我们希望只有一个JSON串参数。如果不是这样,我们就返回一个字符串信息Invalid no of arguments passwd。我们不能从Go直接返回一个error类型给JavaScript。下一节教程会讨论如何进行错误处理。

    我们用args[0].String()来获取输入的JSON。这表示从JavaScript传入的第一个参数。获取输入的JSON后,我们就调用prettyJson函数(第8行),将将结果返回。

    从Go返回一个值给JavaScript时,编译器将自动使用ValueOf函数将Go值转换为JavaScript值。在这个例子中,我们从Go返回的是一个string,它会被编译器用js.ValueOf()函数转换为相应的JavaScript字符串类型。

    我们将FuncOf的返回值赋值给jsonFunc。这样jsonFunc就是一个可以从JavaScript调用的函数了。最后我们返回jsonFunc(第15行)。

    现在我们有了一个可以从JavaScript调用的函数了。最后还差一步。

    我们需要把刚刚创建的这个函数暴露出去,以使得可以从JavaScript调用。方法是,把JavaScript的global对象的formatJSON属性设置为jsonWrapper()返回的js.Func。

    以下这行代码就是干这个的:

    js.Global().Set("formatJSON", jsonWrapper())  

    把这行代码加入到main()函数的最后。在这行代码中,我们将JavaScript的global对象的formatJSON属性设置为jsonWrapper()函数的返回值。现在负责对JSON串进行格式化的jsonFunc函数可以从JavaScript以函数名formatJSON来调用了。

    完整的程序代码如下:

    package main
    
    import (  
        "fmt"
        "encoding/json"
        "syscall/js"
    )
    
    func prettyJson(input string) (string, error) {  
            var raw interface{}
            if err := json.Unmarshal([]byte(input), &raw); err != nil {
                    return "", err
            }
            pretty, err := json.MarshalIndent(raw, "", "  ")
            if err != nil {
                    return "", err
            }
            return string(pretty), nil
    }
    
    func jsonWrapper() js.Func {  
            jsonFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
                    if len(args) != 1 {
                            return "Invalid no of arguments passed"
                    }
                    inputJSON := args[0].String()
                    fmt.Printf("input %s\n", inputJSON)
                    pretty, err := prettyJson(inputJSON)
                    if err != nil {
                            fmt.Printf("unable to convert to json %s\n", err)
                            return err.Error()
                    }
                    return pretty
            })
            return jsonFunc
    }
    
    func main() {  
        fmt.Println("Go Web Assembly")
        js.Global().Set("formatJSON", jsonWrapper())
    }

    我们来编译并测试一下这个程序。

    cd ~/Documents/webassembly/cmd/wasm/  
    GOOS=js GOARCH=wasm go build -o  ../../assets/json.wasm  
    cd ~/Documents/webassembly/cmd/server/  
    go run main.go 

    以上命令将编译wasm二进制并启动我们的web服务器。

    从JavaScript调用Go函数

    我们已经成功地将Go函数暴露给了JavaScript。我们来检查一下它能不能用。

    再次从浏览器打开http://localhost:9090,并打开JavaScript控制台。

    在控制台中输入以下命令:

    formatJSON('{"website":"golangbot.com", "tutorials": {"string":"https://golangbot.com/strings/"}}')  

    以上命令调用了我们从Go暴露出去的formatJSON函数,传入一个JSON参数。敲回车,能否成功?

    对不起:),你得到的是一个错误提示:Error: Go program has already exited

    Error: Go program has already exited

    原因是,当从JavaScript调用的时候,我们的Go程序已经退出了。怎么办?很简单,我们必须确保在JavaScript调用的时候,我们的Go程序还在运行。最简单的办法就是在Go程序中持续等待一个channel。

    func main() {  
            fmt.Println("Go Web Assembly")
            js.Global().Set("formatJSON", jsonWrapper())
            <-make(chan bool)
    }

    在这段代码中,我们在一个channel上持续等待输入。把最后一行代码加入到~/Documents/webassembly/cmd/wasm/main.go中,编译并重新运行。然后在浏览器中再次尝试以下命令:

    formatJSON('{"website":"golangbot.com", "tutorials": {"string":"https://golangbot.com/strings/"}}')

    这一次可以正确打印出格式化的JSON了:

    WebAssembly JSON Formatter using Go

    如果我们不传入参数:

    formatJSON()  

    则会得到以下提示:

    "Invalid no of arguments passed"

    漂亮!我们已经成功地从JavaScript调用了用Go编写的函数。

    本教程的源代码可以从https://github.com/golangbot/webassembly/tree/tutorial1/处获取。

    在下一节教程中,我们将为这个应用创建UI,进行错误处理,并从Go修改浏览器的DOM。

     

     

     

     

    展开全文
  • qt for webassembly环境搭建图文教程

    千次阅读 多人点赞 2021-01-22 15:55:11
    从Qt5.14开始,官方的在线安装提供了qt for webassembly构建套件,这对很多小白来说绝对是个好消息,也绝对是个好东西,好消息是不用再去交叉编译自己生成qt for webassembly的qt库,在线安装版本直接就给你安装好,...
  • 原标题:The world’s easiest introduction to WebAssembly???? 原文链接:The world’s easiest introduction...
  • WebAssembly——从入门到入门

    万次阅读 2018-08-19 17:37:08
    WebAssembly官网上,提出一种观点:传统的网络架构可以分为两层,一层是运行web app的虚拟机,一层是web API。可以理解为虚拟机层用于计算,实现交互功能,而web API层负责实现展示 JS性能瓶颈 一直以来,虚拟机层...
  • 翻译自 Waqas Anwar 2021年3月12日的文章《A Beginner’s Guide To Blazor Server and WebAssembly Application...
  • 本套视频教程主要讲的WebAssembly安全视频教程,从web发展趋势讲到WebAssembly的出现,深入浅出,涉及到的技术内容主要有llvm与Wasm之间的关系, Wasm文件格式,Wasm与c/c++的交互,更深层次的讲了Wasm安全技术,...
  • WebAssembly的基础使用方法

    万次阅读 2018-05-12 14:28:10
    什么是WebAssembly(wasm)?WebAssembly或wasm是一种新的,便携式的,大小和加载时间效率高的格式,适合编译到Web上。- WebAssembly设计一种二进位表示的新语言,但有另外的文字格式可以让你编辑与调试。编译目标...
  • WebAssembly承诺提供一种全新的网络-为用户提供更佳的性能,并为开发人员提供更大的灵活性。 开发人员可以使用多种语言(C,TypeScript,Rust,Ruby,Python)进行选择,而不必局限于使用JavaScript作为客户端网络...
  • WebGL基础水教程 如果您有任何疑问或遇到任何绊脚石,请随时! # You can use any static file server that properly sets the # `application/wasm` mime type cargo install https git clone ...
  • 作者|张翰(门柳)出品|阿里巴巴新零售淘系技术部本文知识点提炼:1、把复杂的 C++框架编译成 WebAssembly。2、在 wasm 模块里调用 DOM API !3、在 js...
  • WebAssembly学习笔记

    千次阅读 2018-03-22 22:54:21
    WebAssembly是最近十年 web 技术发展中最重大的一个新技术。很多人可能都听说过它最重要的一个特性:性能好,运行快。那WebAssembly究竟是什么?是什么使得它性能好运行快的呢?
  • javascript入门by Daniel Simmons 丹尼尔·... WebAssembly入门-仅使用14行JavaScript (Get started with WebAssembly — using only 14 lines of JavaScript) WebAssembly is a brand new web technology with...
  • WebAssembly 安装

    2020-10-23 16:44:18
    编译并运行一个简单的程序 现在,我们已经有了一个完整的工具链,将简单的程序编译成 WebAssembly。不过,这里有一些值得提醒的地方: 在使用 emcc 命令时,要带着 -s WASM=1 参数(不然,默认将会编译成asm.js...
  • 文中所有的代码都可以在 ...在之前的教程中,我们讨论了如何从 Web 浏览器中的 JavaScript 应用程序访问 WebAssembly 函数。 WebAssembly 快问快答 Rust 的 Hello world | WebAssembl...
  • 首先根据官网的教程一步步创建代码,官网链接 创建一个Main.ts文件,代码如下: declare function sayHello(): void; sayHello(); export function add(x: i32, y: i32): i32 { return x + y; } JS调用代码: ...
  • 跟我一起从零开始学习WebAssembly(一)、环境配置-附件资源
  • 优质视频教程福利一:http://www.longstudy.club/tuiguan/js.html 服务器如何搭建博客:http://www.longstudy.club/tuiguan/t1/index.html 点赞再看,微信搜索 【大迁世界】 关注这个没有大厂背景,但有着一股向上...
  • WebAssembly安装环境配置

    千次阅读 2019-12-24 15:40:12
    安装 安装环境Mac OS X mac 下默认有git python(2.7.x);只需要安装cmake cmake安装 cmake 安装可以使用1.brew 2....下载地址 安装完后打开应用 Tools >...How to install Fow Command Line Use 可以看见相关提示三种...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,306
精华内容 522
关键字:

webassembly教程