首页 > 编程语言 >[Rust] Rust开发Wasm运行到支付宝小程序

[Rust] Rust开发Wasm运行到支付宝小程序

时间:2024-01-15 10:55:09浏览次数:36  
标签:支付宝 canvas 程序 Wasm wasm Rust

Rust开发Wasm运行到支付宝小程序

最近参加了支付宝小程序开发者大赛, 把我之前的RustNES项目(任天堂红白机游戏机模拟器, 可以玩小霸王上的马里奥, 冒险岛等)迁移到了支付宝小程序上,
发现相关内容网上的资料比较匮乏, 在此分享一下开发经历.

本项目两大核心点

  1. Rust编译成Wasm运行在小程序环境中
  2. 支付宝小程序支持Canvas+Wasm

Rust编译

Rust编译小程序Wasm与编译到Web环境大体相同, 但小程序的环境受限, dom api等不能直接通过js binding拿到, 尽量不要在小程序中用rust控制js,
我这里使用了feature来区分了web和小程序.

前置条件: Rust环境

  1. 添加wasm工具链 rustup target add wasm32-unknown-unknown
  2. Rust项目适配wasm, 这里简单列出我用到的依赖
// web only
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2.8", features = ["js"] } # 注入缺失js api
js-sys = { version = "0.3.51" } # js 类型
wasm-bindgen = { version = "0.2.74" } # rust 导出 wasm
wasm-logger = { version = "0.2.0" }   # console log 适配
wasm-rgame = { version = "0.0.1" }    # 可选, 我用来做keycode定义

# w3c 标准对象定义
[dependencies.web-sys]
version = "0.3.4"
features = [
  'Document',
  'Element',
  'HtmlCanvasElement',
  'HtmlParagraphElement',
  'KeyboardEvent',
  'WebGl2RenderingContext',
  'WebGlBuffer',
  'WebGlVertexArrayObject',
  'WebGlProgram',
  'WebGlShader',
  'WebGlUniformLocation',
  'WebGlTexture',
  'Window',
  'FocusEvent',
  'File',
  "FileReader",
  # ... 你需要的接口
]
optional = true


[features]
wasm = ["web-sys"]

具体如何适配可以直接搜文章, 也可以到我项目中看代码

  1. 编译 Wasm target

这里没有什么gap, 都是用 wasm-pack 命令(或者配置webpack config)

wasm-pack build --target web --release -d ../$Playground/pkg_miniapp --features wasm,wasm-miniapp --no-default-features

编译好后 pkg_miniapp 就是我们要的 wasm 包.

根据参考文章1, 我们还不能直接在小程序中用, 需要做一些适配.

导入TextEncoder,TextDecoder (文章1中方案是直接拼接文本内容, 我这里搞了个文件)
删除不支持api (new URL/fetch, 这里是用来拉取远程wasm文件的, 小程序不支持)

之后wasm包就可以给小程序用了, 为了方便我们之间把文件夹拷过去.

支付宝小程序适配

首先是wasm, 然后是canvas.

小程序初始化wasm

尽管支付宝官方文档没有写wasm的相关api,但经过实测模拟器,android环境是可以运行的(iOS不行).

import __wbg_init, * as wasm  from "../../pkg/rust_nes";
// 1. 初始化wasm
__wbg_init(wasm_file_array_buf).then(() => {
  // 2. 调用wasm的主函数(应用自己定义), 或在运行时调用wasm导出函数
  wasm.main();
})

但由于网络请求的限制, 我们需要先把wasm文件读到arrayBuffer中, 那么现在的问题就在于如何读取这个文件

三个方案

  1. 本地文件打包: 这个是最合理的, 但没有找到小程序自定义打包配置, 没有走通
  2. 通过my.request下载: 这个上线时需要手动上传到oss上, 预览环境可用
  3. 下载文件: 每次启动游戏都要经过网络把源文件下载下来太浪费流量, 我们可以通过下载文件再读文件的方式获取, 但经过实测读取下载后的文件与源文件内容不一致, 导致加载失败

canvas环境

canvas获取context:

一定要在canvas元素上添加type="webgl"(或canvas2d), 否则拿不到节点

获取代码

my.createSelectorQuery().select('#canvas').node().exec((res) => {
    const canvas = res[0].node;
    const ctx = canvas.getContext('webgl');
    // do something
})

实机运行效果

项目代码,playground代码 欢迎来看看

参考文章:

  1. wasm-pack构建的wasm包如何用于微信小程序

标签:支付宝,canvas,程序,Wasm,wasm,Rust
From: https://www.cnblogs.com/xxrlz/p/17964954

相关文章

  • Slint 文件编辑不能在 Rust 中及时索引
    这个现象在编写VSCode中编写SlintDSL代码时非常常见.表现为修改Slint代码,如:导出新的component/global;为component增加/修改方法,属性,回调;在global中修改结构体属性,修改回调;随后前往Rust的nativecode中试图调用这些方法时,Rust的代码提示无......
  • 学习 Rust 的 15 种方法
    学习Rust的15种方法1.阅读:TheRustBook-https://doc.rust-lang.org/book/2.代码:做Rustlings练习-https://github.com/rust-lang/rustlings3.课程:如何通过以下方式学习Rust-https://learning.accelerant.dev/view/courses/how-to-learn-rust4.阅读:Rust......
  • RUST web框架axum快速入门教程6之测试
    本文主要讨论axum的测试,axum对于测试的支持还是比较完善的,我们可以测试状态码,HTTP头信息,响应体等内容,因为框架实现的原因,其实axum很依赖tower。往期文章:https://youerning.top/post/axum/quickstart-1https://youerning.top/post/axum/quickstart-2https://youerning.top/pos......
  • rust cargo 国内源
    ~/.cargo/config[source.crates-io]registry="https://github.com/rust-lang/crates.io-index"#替换成你目的镜像源replace-with='sjtu'#清华大学[source.tuna]registry="https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"......
  • Rust安装升级国内源
    linuxexportRUSTUP_DIST_SERVER='https://mirrors.ustc.edu.cn/rust-static'exportRUSTUP_UPDATE_ROOT='https://mirrors.ustc.edu.cn/rust-static/rustup'win32$ENV:RUSTUP_DIST_SERVER='https://mirrors.ustc.edu.cn/rust-static'$ENV:R......
  • Rust 从入门到摔门而出门 环境安装 和 Hello, world!
    ###环境安装#### 在Linux或者macOS上安装RustUp环境打开终端,执行下面命令```bashcurl--proto'=https'--tlsv1.2-sSfhttps://sh.rustup.rs|sh```命令不对可以打开[rust官网](https://www.rust-lang.org/learn/get-started)查看最新的rustup脚本连接##......
  • Rust 使用包、Crate 和模块管理不断增长的项目
    目录包和Crate定义模块来控制作用域与私有性在模块中对相关代码进行分组引用模块项目的路径使用pub关键字暴露路径二进制和库crate包的最佳实践super开始的相对路径创建公有的结构体和枚举使用use关键字将路径引入作用域创建惯用的use路径.使用use引入函数使用use引......
  • 支付宝小程序备案流程详解(必看!)
    为什么要小程序备案2023年8月4日,工信部发布了《工业和信息化部关于开展移动互联网应用程序备案工作的通知》,为了落实《中华人民共和国反电信网络诈骗法》《互联网信息服务管理办法》以及《非经营性互联网信息服务备案管理办法》等法律法规要求,在中华人民共和国境内从事互......
  • 17. 从零用Rust编写正反向代理, Rust中一些功能的实现
    wmproxywmproxy是由Rust编写,已实现http/https代理,socks5代理,反向代理,静态文件服务器,内网穿透,配置热更新等,后续将实现websocket代理等,同时会将实现过程分享出来,感兴趣的可以一起造个轮子法项目地址gite:https://gitee.com/tickbh/wmproxygithub:https://github.com/tickbh/wmpr......
  • 16. 从零用Rust编写正反向代理, 反向代理upstream源码实现
    wmproxywmproxy是由Rust编写,已实现http/https代理,socks5代理,反向代理,静态文件服务器,内网穿透,配置热更新等,后续将实现websocket代理等,同时会将实现过程分享出来,感兴趣的可以一起造个轮子法项目wmproxygite:https://gitee.com/tickbh/wmproxygithub:https://github.com/tickbh/......