從 node.js Web 應用中調用 WebAssembly 函數 | WebAssembly 入門教程

node.js + WebAssembly

文中所有的代碼都可以在 https://github.com/second-state/wasm-learning/tree/master/nodejs/hello 中找到

在之前的教程中,我們討論瞭如何從 Web 瀏覽器中的 JavaScript 應用程序訪問 WebAssembly 函數。

  1. WebAssembly 快問快答
  2. Rust 的 Hello world | WebAssembly 入門教程
  3. 5分鐘實現一個簡單的 WebAssembly 應用|WebAssembly 入門教程
  4. 如何將字符串從 JavaScript 傳入 Wasm/Rust | WebAssembly 入門教程

然而,或許你已經注意到,服務器端的 WebAssembly 有很多很好的用例,尤其是人工智能、區塊鏈和大數據應用方向。

在這個例子中,將展示如何將 Rust 中編寫的 WebAssembly 函數集成到服務器上的 node.js 應用程序中。

我們以微服務的方式提供 WebAssembly 函數。

演示應用程序的結構如下:

  • 主機應用程序是一個用 JavaScript 編寫的 node.js web 應用程序,調用 WebAssembly 函數
  • WebAssembly 字節碼程序是用 Rust 編寫的,由 node.js 的 web 應用程序調用。

[查看源代碼和教程]((https://github.com/second-state/wasm-learning/blob/master/nodejs/hello.md)

設置

與前面的教程一樣,我們使用 wasm-pack 工具編譯 Rust 源代碼並生成相應的 JavaScript 模塊。這種模塊使得在 JavaScript 和 Rust 函數之間傳遞複雜的動態數據變得非常容易。想要深入瞭解的同學,可以閱讀《WebAssembly 中的字符串》

接下來,按照下面的步驟安裝Rust和wasm-pack 工具。

# 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 wasm-pack tools
$ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

Rust 寫的 WebAssembly 程序

在這個示例中,Rust 程序在“hello” 後面追加輸入字符串。

創建一個新的cargo項目。

注意:由於這個程序是從主機應用程序調用的,而不是作爲獨立的可執行文件運行,因此我們將創建一個 hello 項目。

···
$ cargo new --lib hello
$ cd hello

編輯 Cargo.toml 文件添加 [lib] 部分. 它告訴編譯器在哪能找到庫的源代碼,以及如何生成字節碼輸出。同時,我們也需要在這添加 wasm-bindgen 的依賴項。這是使用 wasm-pack的用途,生成綁定 JavaScript 的 rust webassembly程序

[lib]
name = "hello_lib"
path = "src/lib.rs"
crate-type =["cdylib"]
[dependencies]
wasm-bindgen = "0.2.50"

下面是Rust 程序 src/lib.rs 的內容。實際上,我們可以在這個庫文件中定義多個外部函數,並且所有這些函數都可以通過 WebAssembly 在主機 JavaScript 應用程序中使用。

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn say(s: String) -> String {
  let r = String::from("hello ");
  return r + &s;
}

接下來,您可以將 Rust 源代碼編譯成 WebAssembly 字節碼,併爲 node.js 主機環境生成相應的 JavaScript 模塊。

$ wasm-pack build --target nodejs

結果是以下三個文件.
.wasm 文件是 WebAssembly 字節碼程序;
.js 文件用於 JavaScript 模塊;

Pkg / hello lib bg. wasm
Pkg / hello lib bg. js
Pkg / hello lib.js

Node.Js 主機應用程序

接下來,讓我們爲 node.js web 應用程序創建一個節點文件夾,複製生成的 JavaScript 模塊文件。

$mkdir node
$cp pkg / hello lib bg. wasm node /
$cp pkg / hello lib bg. js node /
$cp pkg / hello lib.js node /

使用生成的 hello_lib.js, 在 JavaScript 中調用 WebAssembly 函數是非常容易的。

下面是節點應用程序 app.js。 它只是從生成的模塊中導入 say () 函數。 節點應用程序從傳入的 httpget 請求中獲取 name 參數,並用“ hello name”進行響應。

const { say } = require('./hello_lib.js');

const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = 8080;

const server = http.createServer((req, res) => {
  const queryObject = url.parse(req.url,true).query;
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end(say(queryObject['name']));
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

按照以下方式啓動 node.js 應用服務器。

$ node app.js
Server running at http://127.0.0.1:8080/

然後,就可以測試了。

$ curl http://127.0.0.1:8080/?name=Wasm
hello Wasm

下一步是什麼呢?

現在 Web 服務可以將計算量大、不安全和新穎的硬件訪問任務轉移到 WebAssembly 中。 我相信,將有更多用例將會出現。 敬請期待!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章