#json-rpc #websocket #json-rpc-client #json #rpc-client #websocket-client

reconnecting-jsonrpsee-ws-client

自动重新连接的jsonrpc-ws客户端。警告:在重新连接时可能会丢失订阅消息。

7个不稳定版本 (3个破坏性更新)

0.4.3 2024年6月25日
0.4.2 2024年4月24日
0.3.0 2024年2月8日
0.2.0 2024年1月24日
0.1.0 2024年1月4日

#115 in WebAssembly

Download history 460/week @ 2024-05-04 482/week @ 2024-05-11 466/week @ 2024-05-18 539/week @ 2024-05-25 764/week @ 2024-06-01 710/week @ 2024-06-08 848/week @ 2024-06-15 1541/week @ 2024-06-22 1031/week @ 2024-06-29 1905/week @ 2024-07-06 1369/week @ 2024-07-13 1189/week @ 2024-07-20 1186/week @ 2024-07-27 1817/week @ 2024-08-03 2143/week @ 2024-08-10 2598/week @ 2024-08-17

7,890 每月下载次数
5 个crate中使用 (via subxt)

MIT 协议

58KB
1K SLoC

reconnecting-jsonrpsee-ws-client

jsonrpsee ws客户端的包装crate,在内部自动重新连接;否则需要重启。它支持几种重试策略,如指数退避,但只要实现 Iterator<Item = Duration>,就可以使用自定义策略。

默认情况下,该库会重新传输挂起的调用并重新建立连接终止时关闭的订阅,但也可以禁用此功能并自行管理。

例如,您可能不想重新订阅具有副作用或完全重试的订阅。然后库公开了 request_with_policysubscribe_with_policy 来支持这一点

    let mut sub = client
        .subscribe_with_policy(
            "subscribe_lo".to_string(),
            rpc_params![],
            "unsubscribe_lo".to_string(),
            // Do not re-subscribe if the connection is closed.
            CallRetryPolicy::Retry,
        )
        .await
        .unwrap();

棘手的部分是订阅,在重新连接时可能会丢失一些通知,但无法知道是哪些。

在某些情况下,丢失的订阅通知可能非常重要,因此不建议使用此库。

有一种方法可以确定重新连接需要多长时间

    // Print when the RPC client starts to reconnect.
    loop {
        rpc.reconnect_started().await;
        let now = std::time::Instant::now();
        rpc.reconnected().await;
        println!(
            "RPC client reconnection took `{} seconds`",
            now.elapsed().as_secs()
        );
    }

示例

use reconnecting_jsonrpsee_ws_client::{rpc_params, Client, ExponentialBackoff, PingConfig};
use std::time::Duration;

async fn run() {
    // Create a new client with with a reconnecting RPC client.
    let client = Client::builder()
        // Reconnect with exponential backoff and if fails more then 
        // 10 retries we give up and terminate.
        .retry_policy(ExponentialBackoff::from_millis(100).take(10))
        // Send period WebSocket pings/pongs every 6th second and
        // if ACK:ed in 30 seconds then disconnect.
        //
        // This is just a way to ensure that the connection isn't
        // idle if no message is sent that often
        //
        // This only works for native.
        .enable_ws_ping(
            PingConfig::new()
                .ping_interval(Duration::from_secs(6))
                .inactive_limit(Duration::from_secs(30)),
        )
        .build("ws://127.0.0.1:9944".to_string())
        .await
        .unwrap();

    // make a JSON-RPC call
    let json = client
        .request("say_hello".to_string(), rpc_params![])
        .await
        .unwrap();

    // make JSON-RPC subscription.
    let mut sub = client
        .subscribe(
            "subscribe_lo".to_string(),
            rpc_params![],
            "unsubscribe_lo".to_string(),
        )
        .await
        .unwrap();
    let notif = sub.next().await.unwrap();
}

依赖项

~4–15MB
~181K SLoC