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-serialize
feature),配合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
和Error
trait, 而是转换成JsValue,供外部js来try...catch
1 |
|
调用list和get, 并发地获取数据
1 | let list = kv::list(kv).await?; |