+-
「入门」在Node.js中使用Rust

最近有个活动,竟然快结束了才看到,能获得一个小树莓派,还可以学点知识,何乐不为?

准备开工

入门文档学习 使用ssvm构建一个nodejs应用,调用rust库 创建一个小demo

环境准备

rust

系统环境已经预装了rust(rustc 1.44.0),跳过rust环境部署。

PS: 系统为Manjaro

Node.js

没有nodejs环境,需要安装:yay -S nodejs npm

安装依赖

yay -S community/libcurl-gnutls

ssvm工具链

安装ssvm的工具链:npm install ssvmup

使用官方的npm install -g ssvmup遇到权限问题,可以使用--unsafe-perm

安装ssvm

安装ssvm: npm install ssvm

开始构建HELLO程序

Fork这个仓库:repo

在目录下进行build

ssvm-nodejs-starter git:(master) ssvmup build
ssvmup在安装时如果没有-g选项,会安装在$HOME/.config/目录下,可用ln重新为ssvmup创建一个链接

不过似乎手动安装需要的第三方库有点问题:

[INFO]: Installing wasm-bindgen...
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { description: "Couldn\'t connect to server", code: 7, extra: None }', src/install/mod.rs:182:9

简单搜索发现需要联网0.0,但是我有网络啊,那就可能要梯子?

编译成功后:

Your wasm pkg is ready to publish at /home/tmacy/ssvm-nodejs-starter/pkg.

然而

开始运行服务时出现了错误:

 node node/app.js 
terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
  what():  filesystem error: directory iterator cannot open directory: No such file or directory [/usr/lib/x86_64-linux-gnu]
[1]    2418864 abort (core dumped)  node node/app.js

看起来似乎时cxx11的链接有问题,可能是第三方动态库的编译环境是ubuntu?
官方的环境要求看来是有原因的0.0

还是Docker大法好!换docker试试?然而可怜的网速,拖镜像太慢--!

仔细想了一下,直接建立软链接解决问题:sudo ln -s /usr/lib /usr/lib/x86_64-linux-gnu

终于输出了想要的内容:curl http://127.0.0.1:3000/?name=Wasm
hello Wasm

一个简单的web教学例子

1.直接修改hello项目,在cargo.toml增加依赖:

serde \= { version \= "1.0", features \= \["derive"\] }
serde\_json \= "1.0"
在node目录下增加public目录,创建index.html,用来显示页面 增加node的server.js,设置nodejs的服务段,解析/solve中的参数,传递给rust库。

Node.js 应用程序从用户输入的表单中读取数据,将数据作为数组传递到 solve 函数中,然后将返回值放入 HTTP 响应中。

app.post('/solve', function (req, res) {
  var a = parseFloat(req.body.a);
  var b = parseFloat(req.body.b);
  var c = parseFloat(req.body.c);
  res.send(solve([a, b, c]))
})

solve函数的引入:

const { solve } = require('../pkg/quadratic_lib.js');
在src/lib.rs中设置solve函数,处理计算问题
pub fn solve(params: &str) -> String {
    let ps: (f32, f32, f32) = serde_json::from_str(&params).unwrap();
    let discriminant: f32 = (ps.1 * ps.1) - (4. * ps.0 * ps.2);
    let mut solution: (f32, f32) = (0., 0.);
    if discriminant >= 0. {
        solution.0 = (((-1.) * ps.1) + discriminant.sqrt()) / (2. * ps.0);
        solution.1 = (((-1.) * ps.1) - discriminant.sqrt()) / (2. * ps.0);
        return serde_json::to_string(&solution).unwrap();
    } else {
        return String::from("not real numbers");
    }
}

运行:

node node/server.js

在浏览器中打开:
http://localhost:8080

截图显示