cf-workers-wasm
在cloudflare workers上体验一下wasm:)
这两天闲来无事,用rust重写了一下飞机订阅程序,托管于cf workers. 程序功能比较简单,利用cf-kv存储节点配置,收到请求以后再返回分享连接。
网上关于wasm的资料已经比较丰富,rustwasm本身就有文档。下面稍微记录一下我的摸索过程:
接口
相比单独写js或rust, 用wasm还需要解决rust和js的交互问题。比如由rust导出方法,供js调用:
1 |
|
如果要在rust中调用js方法,则需要先声明:
1 |
|
一般都会导入js-sys, web-sys这两个crate,它们封装了js中常用的类型和方法,比如js-sys::ArrayBuffer web-sys::Request, web-sys::Response (rust-analyzer有时推断不出这些类型,需要手动标记,不然没有提示)
数据
为了方便使用,还要把JsValue转换成合适的rust类型。基本类型可以直接互换,Option<T>::None对应js中的null; 另外JsValue还提供了from_serde()和into_serde()这两个方法(需要启用wasm-bidgen的serde-serializefeature),配合serde的宏,可以很方便的实现类型转换:
1 |
|
异步
rust中的Future和js的Promise也是可以相互转换的,需要导入wasm_bidgen_futures,里面有future_to_promise和spawn_local方法。此外,wasm_bidgen的宏也可以直接用在async fn上,会自动实现Future和Promise的转换。Future返回值为Result<JsValue, JsValue>,分别对应resolve和reject。如果想要实现Promise.all的效果,只要对着多个Future用join就行了
使用kv
官网的教程已经给出了get和put的调用方法,可以自己如法炮制一个list&delete
首先声明方法:
1 |
|
wasm_bidgen必须添加structural参数,因为WorkersKv是外部js传入的kv binding,类型未知(不是JsValue),见The structural flag
定义返回值类型(get返回String, 而JsValue已经实现了From<String>, 因此不必再定义一个GetResult)
1 |
|
再封装一下方法,方便调用
1 | pub async fn get<T: Into<JsValue>>(kv: &WorkersKv, key: T) -> Result<String> { |
上面的四个函数都用了自定义的Error和Result, 配合?会很方便。这里没有实现Display和Errortrait, 而是转换成JsValue,供外部js来try...catch
1 |
|
调用list和get, 并发地获取数据
1 | let list = kv::list(kv).await?; |