39 个版本 (14 个重大更改)
| 新 0.17.0 | 2024 年 8 月 19 日 |
|---|---|
| 0.15.0 | 2024 年 7 月 26 日 |
| 0.14.2 | 2024 年 7 月 26 日 |
| 0.11.0 | 2024 年 2 月 25 日 |
| 0.1.2 | 2022 年 9 月 21 日 |
#11 在 WebSocket
2,231 每月下载量
用于 16 个 crates (6 个直接)
455KB
10K SLoC
workflow-rpc (wRPC)
是 workflow-rs 应用程序框架的一部分。
在 workflow-websocket crate 的基础上构建的 RPC 功能,提供通过 WebSocket 连接异步数据中继,支持自定义高性能的 Borsh 和扩展的 JSON-RPC 协议。
特性
- 高性能 Borsh 消息编码协议
- 基于可序列化泛型的 RPC 方法和处理程序声明
- 客户端到服务器的 RPC 方法调用
- 客户端到服务器的通知消息
- 服务器到客户端的通知消息
- 服务器端握手脚手架,用于自定义连接协商
- 易于保留连接数据结构,用于发布异步客户端通知
这个 crate 提供了一个高性能、专注于 Rust 的通信层。远程函数调用是通过一个单函数完成的,该函数包含两个泛型 rpc.call<Request,Response>().await?,其中请求和响应数据类型必须实现使用 Borsh 和 Serde JSON 序列化和反序列化特质的序列化。
数据通过WebSocket二进制消息帧以Borsh编码传输,通过文本帧以JSON编码传输。
Borsh协议
由于使用了泛型来定义id和op(方法)类型,Borsh头部消息的大小可能不同,确保客户端和服务器之间的一致性是开发者的责任。在连接打开阶段可以通过握手协商协议版本。
Borsh协议使用以下格式:请求:[Option,Option,Payload]
id: Id:一个泛型用户定义类型,通常是基于u32或u64的类型(如果是通知消息,则为Option:None)。op: Ops:一个泛型用户定义类型,通常是表示操作的枚举类型。payload: Payload:实现了BorshSerialize, BorshDeserialize, Serialize和Deserialize特质的任何数据类型。响应:[Option,Kind,Option,Payload]id: Id:一个泛型用户定义类型(如果是通知消息,则为Option:None)。kind: Kind:一个字节表示消息类型:0x01:成功,0x02:错误,0xff:通知ops: Ops:一个泛型用户定义类型,通常是表示操作的枚举类型。payload: Payload:包含Result<UserType,ServerError>的序列化数据。
注意:Borsh提供高性能的序列化和反序列化,然而,在RPC中传输的数据结构格式变化可能会导致服务器和客户端之间的协议不匹配。使用Borsh时,您需要从相同的代码库构建服务器和客户端。
为了提供版本解析,可以将数据结构封装到枚举中,如下所示
enum MyEnum {
V1(DataStructureV1),
V2(DataStructureV2),
...
}
wRPC JSON协议
JSON协议使用Serde (serde-json) 序列化。
JSON消息格式在JSON-RPC协议的基础上进行了扩展,如下所示:客户端消息
id:可选,如果是通知消息则不存在method:RPC方法或通知名称params:消息数据- 服务器端消息
method:RPC方法或通知名称id:可选,如果是通知消息则不存在params:消息(响应或通知)数据error:如果RPC方法产生错误,则包含错误数据code:错误代码(自v0.3.0起始终为0x00)message:错误信息字符串data:额外的错误数据(自v0.3.0起始终不存在`)JSON-RPC和JSON-wRPC之间的区别- JSON-RPC 2.0规范不支持服务器端(服务器到客户端)的通知。
- JSON-RPC 2.0 在每个消息中包含一个
json-rpc="2.0"属性。这对于 wRPC 来说是多余的 - wRPC 握手可以用来描述协议版本。
Node.js 兼容性
注意: workflow-rpc 是基于 workflow-websocket 库构建的。要在 Node.js 环境中使用 workflow-rpc,需要在加载 WASM32 库之前引入一个 W3C WebSocket 对象来模拟 Web 浏览器中可用的全局 WebSocket 对象。WebSocket NPM 模块提供了与 W3C WebSocket 兼容的实现,可以使用如下方式使用
// WebSocket
globalThis.WebSocket = require('websocket').w3cwebsocket;
// Load WASM32 library ...
依赖
~19–38MB
~562K SLoC