#socket-io #protocols #engineio #client-server #networking #client

my_rust_socketio

基于 rust_socken_io 开发,但修复了无限重连的问题

3 个版本

0.0.3 2023年6月16日
0.0.2 2023年6月16日
0.0.1 2023年6月16日

#119 in WebSocket

MIT 许可证

160KB
3K SLoC

Rust-socketio-client

使用 Rust 编程语言编写的 socket.io 客户端实现。此实现目前支持 socket.io 协议的第 5 版,因此也支持 engine.io 协议的第 4 版。如果您使用此客户端遇到任何连接问题,请确保服务器使用至少 engine.io 协议的第 4 版。有关 async 版本的信息见下文。

示例用法

将以下内容添加到您的 Cargo.toml 文件中

my_rust_socketio = "0.0.2"

然后您可以运行以下示例代码

use rust_socketio::{ClientBuilder, Payload, RawClient};
use serde_json::json;
use std::time::Duration;

// define a callback which is called when a payload is received
// this callback gets the payload as well as an instance of the
// socket to communicate with the server
let callback = |payload: Payload, socket: RawClient| {
       match payload {
           Payload::String(str) => println!("Received: {}", str),
           Payload::Binary(bin_data) => println!("Received bytes: {:#?}", bin_data),
       }
       socket.emit("test", json!({"got ack": true})).expect("Server unreachable")
};

// get a socket that is connected to the admin namespace
let socket = ClientBuilder::new("https://127.0.0.1:4200")
     .namespace("/admin")
     .on("test", callback)
     .on("error", |err, _| eprintln!("Error: {:#?}", err))
     .connect()
     .expect("Connection failed");

// emit to the "foo" event
let json_payload = json!({"token": 123});
socket.emit("foo", json_payload).expect("Server unreachable");

// define a callback, that's executed when the ack got acked
let ack_callback = |message: Payload, _| {
    println!("Yehaa! My ack got acked?");
    println!("Ack data: {:#?}", message);
};

let json_payload = json!({"myAckData": 123});
// emit with an ack
socket
    .emit_with_ack("test", json_payload, Duration::from_secs(2), ack_callback)
    .expect("Server unreachable");

socket.disconnect().expect("Disconnect failed")

此 crate 的主要入口点是 ClientBuilder,它提供了一种轻松配置所需方式中的套接字的方法。当在构建器上调用 connect 方法时,它返回一个已连接客户端,然后可以使用它向特定事件发送消息。一个客户端只能连接到一个命名空间。如果您需要监听不同命名空间中的消息,则需要分配多个套接字。

文档

此 crate 的文档可以在 docs.rs 上找到。

当前功能

此实现现在支持 此处 提到的 socket.io 协议的所有功能。它通常尽可能多地使用 WebSocket。这意味着大多数情况下,只有打开请求使用 HTTP,一旦服务器表明它能够升级到 WebSocket,就会执行升级。但如果此升级失败或服务器没有提及升级的可能性,则使用 HTTP 长轮询(如协议规范中指定)。以下是可能的用例概述

  • 连接到服务器。
  • 注册以下事件类型的回调
    • 打开
    • 关闭
    • 错误
    • 消息
    • 自定义事件,如 "foo"、"on_payment" 等。
  • 向服务器发送 JSON 数据(通过 serde_json,它提供安全处理)。
  • 向服务器发送 JSON 数据并接收 ack
  • 发送和处理二进制数据。

异步版本

本库提供了使用tokio作为执行运行时在异步环境中执行的能力。请注意,当前的异步实现仍然是实验性的,接口随时可能发生变化。异步的ClientClientBuilder支持与同步版本类似的接口,并位于asynchronous模块中。为了启用支持,您需要启用async功能标志。

rust_socketio = { version = "0.4.1-alpha.1", features = ["async"] }

以下代码展示了上述示例的异步实现

use futures_util::FutureExt;
use rust_socketio::{
    asynchronous::{Client, ClientBuilder},
    Payload,
};
use serde_json::json;
use std::time::Duration;

#[tokio::main]
async fn main() {
    // define a callback which is called when a payload is received
    // this callback gets the payload as well as an instance of the
    // socket to communicate with the server
    let callback = |payload: Payload, socket: Client| {
        async move {
            match payload {
                Payload::String(str) => println!("Received: {}", str),
                Payload::Binary(bin_data) => println!("Received bytes: {:#?}", bin_data),
            }
            socket
                .emit("test", json!({"got ack": true}))
                .await
                .expect("Server unreachable");
        }
        .boxed()
    };

    // get a socket that is connected to the admin namespace
    let socket = ClientBuilder::new("https://127.0.0.1:4200/")
        .namespace("/admin")
        .on("test", callback)
        .on("error", |err, _| {
            async move { eprintln!("Error: {:#?}", err) }.boxed()
        })
        .connect()
        .await
        .expect("Connection failed");

    // emit to the "foo" event
    let json_payload = json!({"token": 123});
    socket
        .emit("foo", json_payload)
        .await
        .expect("Server unreachable");

    // define a callback, that's executed when the ack got acked
    let ack_callback = |message: Payload, _: Client| {
        async move {
            println!("Yehaa! My ack got acked?");
            println!("Ack data: {:#?}", message);
        }
        .boxed()
    };

    let json_payload = json!({"myAckData": 123});
    // emit with an ack
    socket
        .emit_with_ack("test", json_payload, Duration::from_secs(2), ack_callback)
        .await
        .expect("Server unreachable");

    socket.disconnect().await.expect("Disconnect failed");
}

此存储库的内容

此存储库包含socket.io协议的Rust实现以及底层的engine.io协议。

关于engine.io协议的详细信息可以在此处找到

此处是socket.io协议的规范

查看组件图,以下部分已实现(来源:https://socketio.node.org.cn/images/dependencies.jpg

许可证

MIT

依赖项

~7–21MB
~328K SLoC