Crates.io | workflow-rpc |
lib.rs | workflow-rpc |
version | 0.18.0 |
source | src |
created_at | 2022-08-22 11:27:59.731978 |
updated_at | 2024-09-07 16:59:44.882004 |
description | Workflow RPC (wRPC) framework based on the workflow-websocket crate offering native & in-browser (WASM32) clients and a native server (based on tokio & tungstenite). wRPC supports custom Borsh and JSON protocols with use of generics for RPC method declarations. |
homepage | |
repository | https://github.com/workflow-rs/workflow-rs |
max_upload_size | |
id | 650307 |
size | 109,362 |
workflow-rpc
(wRPC)
Part of the workflow-rs
application framework.
RPC functionality built on top of the workflow-websocket
crate offering asynchronous data relay over WebSocket connections supporting a custom high-performance Borsh
and an extended JSON-RPC
protocols.
This crate provides a high performance, Rust-focused, communication layer. The remote function invocation is done via a single function with two generics rpc.call<Request,Response>().await?
where the request and response data types must implement serlialization using both Borsh and Serde JSON serialization and deserialization traits.
The data is transmitted via WebSocket binary message frames for Borsh encoding and via text frames for JSON encoding.
Due to use of generics for id
and op
(method) types, Borsh header messages can vary in size and it is the responsibility of the developer
to ensure consistency between client and server. Protocol versioning can be negotiated using a handshake during the connection opening phase.
The following format is used by the Borsh Protocol:
Request: [Option
id: Id
: a generic user-defined type, typically u32 or u64-based type (Option:None
if the message is a notification).op: Ops
: a generic user-defined type, typically an enum
representing the operation.payload: Payload
: Any data type that implements BorshSerialize, BorshDeserialize, Serialize and Deserialize traits.
Response: [Optionid: Id
: a generic user-defined type (Option:None
if the message is a notification)kind: Kind
: a byte representing message type: 0x01
: Success, 0x02
: Error, 0xff
: Notificationops: Ops
: a generic user-defined type, typically an enum
representing the operation.payload: Payload
: serialized data containing Result<UserType,ServerError>
NOTE: Borsh provides high-performance serialization and deserialization, however, the change in the data structure formats transported across RPC can result in the protocol mismatch between server and client. When using Borsh it is your responsibility to build both server and client from the same codebase.
To provide version resolution, data structures can be encapsulated into enums as follows:
enum MyEnum {
V1(DataStructureV1),
V2(DataStructureV2),
...
}
JSON protocol uses Serde (serde-json) serialization.
JSON message format extends on top of JSON-RPC protocol as follows: Client-side message:
id
: optional, absent if the message is a notificationmethod
: RPC method or notification nameparams
: message data
Server-side message:id
: optional, absent if message is a notificationmethod
: RPC method or notification nameparams
: message (response or notification) dataerror
: error data if the RPC method produced an error
error
data field contains:code
: error code (as of v0.3.0 always 0x00
)message
: error message stringdata
: additional error data (as of v0.3.0 always absent`)
Differences between JSON-RPC and JSON-wRPC:result
property in the response. wRPC returns params
property in case of both response and notification.json-rpc="2.0"
property in every message. This is redundant for wRPC - wRPC handshake can be used to describe protocol version.NOTE: workflow-rpc
is built on top of the workflow-websocket
crate.
To use workflow-rpc
in the Node.js environment, you need to introduce a W3C WebSocket object before loading the WASM32 library
to simulate the global WebSocket
object available in Web Browsers.
The WebSocket NPM module provides W3C WebSocket compatible implementation and can
be used as follows:
// WebSocket
globalThis.WebSocket = require('websocket').w3cwebsocket;
// Load WASM32 library ...