Socket.io client written in Rust

Overview

Latest Version docs.rs Build and code style Test codecov

Rust-socketio-client

An implementation of a socket.io client written in the rust programming language. This implementation currently supports revision 5 of the socket.io protocol and therefore revision 4 of the engine.io protocol. If you have any connection issues with this client, make sure the server uses at least revision 4 of the engine.io protocol. Information on the async version can be found below.

Example usage

Add the following to your Cargo.toml file:

rust_socketio = "0.4.1"

Then you're able to run the following example code:

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("http://localhost: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")

The main entry point for using this crate is the ClientBuilder which provides a way to easily configure a socket in the needed way. When the connect method is called on the builder, it returns a connected client which then could be used to emit messages to certain events. One client can only be connected to one namespace. If you need to listen to the messages in different namespaces you need to allocate multiple sockets.

Documentation

Documentation of this crate can be found up on docs.rs.

Current features

This implementation now supports all of the features of the socket.io protocol mentioned here. It generally tries to make use of websockets as often as possible. This means most times only the opening request uses http and as soon as the server mentions that he is able to upgrade to websockets, an upgrade is performed. But if this upgrade is not successful or the server does not mention an upgrade possibility, http-long polling is used (as specified in the protocol specs). Here's an overview of possible use-cases:

  • connecting to a server.
  • register callbacks for the following event types:
    • open
    • close
    • error
    • message
    • custom events like "foo", "on_payment", etc.
  • send JSON data to the server (via serde_json which provides safe handling).
  • send JSON data to the server and receive an ack.
  • send and handle Binary data.

Async version

This library provides an ability for being executed in an asynchronous context using tokio as the execution runtime. Please note that the current async implementation is still experimental, the interface can be object to changes at any time. The async Client and ClientBuilder support a similar interface to the sync version and live in the asynchronous module. In order to enable the support, you need to enable the async feature flag:

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

The following code shows the example above in async fashion:

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("http://localhost: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");
}

Content of this repository

This repository contains a rust implementation of the socket.io protocol as well as the underlying engine.io protocol.

The details about the engine.io protocol can be found here:

The specification for the socket.io protocol here:

Looking at the component chart, the following parts are implemented (Source: https://socket.io/images/dependencies.jpg):

Licence

MIT

Comments
  • chore(deps): bump serde from 1.0.152 to 1.0.160

    chore(deps): bump serde from 1.0.152 to 1.0.160

    Bumps serde from 1.0.152 to 1.0.160.

    Release notes

    Sourced from serde's releases.

    v1.0.160

    v1.0.159

    • Accept empty #[serde()] attribute (#2422)

    v1.0.158

    • Fix "expected serde crate attribute to be a string" error when using macro_rules metavariable inside of serde attribute: #[serde(crate = $serde_path)] (#2409)

    v1.0.157

    • Update syn dependency to 2.x

    v1.0.156

    • Documentation improvements

    v1.0.155

    • Support Serialize and Deserialize impls for core::ffi::CStr and alloc::ffi::CString without "std" feature (#2374, thanks @​safarir)

    v1.0.154

    • Fix "undeclared lifetime" error in generated code when deriving Deserialize for an enum with both flatten and 'static fields (#2383, thanks @​Mingun)

    v1.0.153

    • Support serde(alias = "…") attribute used inside of flattened struct (#2387, thanks @​bebecue)
    Commits
    • 0c6a2bb Release 1.0.160
    • a80d830 Merge pull request #2426 from compiler-errors/dont-doc-private
    • 5f3fd99 Make serializer/deserializer internals doc(hidden)
    • d6de911 Release 1.0.159
    • 04af322 Merge pull request #2422 from dtolnay/emptyattr
    • 4cb8d07 Accept empty #[serde()] attribute
    • 6ab55a1 Add regression test for issue 2415
    • acfd19c Release serde_derive_internals 0.27.0
    • e305810 Release 1.0.158
    • dc200a6 Reformat comments of non-public serde_derive internals
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • chore(deps): bump regex from 1.7.1 to 1.7.3

    chore(deps): bump regex from 1.7.1 to 1.7.3

    Bumps regex from 1.7.1 to 1.7.3.

    Changelog

    Sourced from regex's changelog.

    1.7.3 (2023-03-24)

    This is a small release that fixes a bug in Regex::shortest_match_at that could cause it to panic, even when the offset given is valid.

    Bug fixes:

    1.7.2 (2023-03-21)

    This is a small release that fixes a failing test on FreeBSD.

    Bug fixes:

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • chore(deps): bump thiserror from 1.0.38 to 1.0.40

    chore(deps): bump thiserror from 1.0.38 to 1.0.40

    Bumps thiserror from 1.0.38 to 1.0.40.

    Release notes

    Sourced from thiserror's releases.

    1.0.40

    • Update syn dependency to 2.x

    1.0.39

    • Set html_root_url attribute
    Commits
    • 3cec8c4 Release 1.0.40
    • 2c65cea Merge pull request #227 from dtolnay/syn
    • fb8b81f Update to syn 2
    • 0e45dde Merge pull request #226 from dtolnay/tokenspan
    • 490dc01 Eliminate unneeded use of Spanned trait on single tokens
    • f729af9 Release 1.0.39
    • 391ec2b Set html_root_url
    • a2d1ed1 Enable type layout randomization in CI on nightly
    • 7aaa03d Show enabling of nightly tests as a CI step
    • 0010b0f Support a manual trigger on CI workflow
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • chore(deps): bump serde_json from 1.0.95 to 1.0.96

    chore(deps): bump serde_json from 1.0.95 to 1.0.96

    Bumps serde_json from 1.0.95 to 1.0.96.

    Release notes

    Sourced from serde_json's releases.

    v1.0.96

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • chore(deps): bump tungstenite from 0.17.3 to 0.19.0

    chore(deps): bump tungstenite from 0.17.3 to 0.19.0

    Bumps tungstenite from 0.17.3 to 0.19.0.

    Changelog

    Sourced from tungstenite's changelog.

    0.19.0

    • Update TLS dependencies.
    • Exchanging base64 for data-encoding.

    0.18.0

    • Make handshake dependencies optional with a new handshake feature (now a default one!).
    • Return HTTP error responses (their HTTP body) upon non 101 status codes.
    Commits
    • 869a67c Bump version
    • a873bef Merge pull request #345 from mlemesle/fix/webpki-error-variant
    • 1f6c62d Fix not compiling features rustls-tls-native-roots and rustls-tls-webpki-roots
    • 92d65e1 Update webpki-roots requirement from 0.22 to 0.23 (#343)
    • 67e25fd Merge pull request #341 from snapview/dependabot/cargo/rustls-0.21.0
    • 1422d47 Update rustls requirement from 0.20.0 to 0.21.0
    • 42b8797 Revert "Add permessage-deflate support"
    • edb2377 Add permessage-deflate support
    • e1033af Merge pull request #337 from A5rocks/fix-frame-display
    • 5125c59 Display correct payload in Frame::fmt
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
Owner
Hand of Midas
Touch you with the hand of midas
Hand of Midas
Safe Rust crate for creating socket servers and clients with ease.

bitsock Safe Rust crate for creating socket servers and clients with ease. Description This crate can be used for Client <--> Server applications of e

Lorenzo Torres 3 Nov 25, 2021
A rust implementation of websock/socket proxy. Support noVNC

websockify-rs: WebSockets support for any application/server This is a rust implement of the websockify-js, which is part of the noVNC project. At the

null 3 Jan 10, 2023
General-purpose asynchronous socket stream.

async-socket This crate implements a general-purpose asynchronous socket. The Socket implements AsyncRead, AsyncWrite, Stream and Clone traits and thu

Kristijan Sedlak 3 Oct 20, 2021
Hammerspoon plugin and API to interact with Yabai socket directly

Yabai.spoon NOTE: no longer using it or intending to maintain it see #2. Yabai.spoon is lua 5.4 library to interact with yabai socket directly within

null 2 May 17, 2022
Acts as an IRC server and a nostr client. Connect with your IRC client using your nostr private key as the password.

nostr-irc Acts as an IRC server and a nostr client. Connect with your IRC client using your nostr private key as the password. Experimental code, use

null 11 Dec 26, 2022
A ddns client written in Rust.

ddns-rs ready for use with one cloudflare A/AAAA record ?? A ddns client written in Rust. Features get public ip cloudflare (A or AAAA record) toml co

Ric Li 1 Oct 25, 2022
An online version of the popular game four in a row, written in Rust on the server side and Flutter + Dart on the client.

Four in a Row - Server An online version of the popular game four in a row, written in Rust on the server side and Flutter + Dart on the client. Downl

Filippo Orrù 8 Sep 16, 2022
Fast Discord RPC Client written in Rust

Discord RPC Client Examples Big image, small image, details and one button discordrpc -c 942151169185316874 -d 'untypeable nickname' --button-1-text '

Oskar 10 Jan 1, 2023
RDE1 (Rusty Data Exfiltrator) is client and server tool allowing auditor to extract files from DNS and HTTPS protocols written in Rust. 🦀

Information: RDE1 is an old personal project (end 2022) that I didn't continue development on. It's part of a list of projects that helped me to learn

Quentin Texier (g0h4n) 32 Oct 6, 2023
FTP client for Rust

rust-ftp FTP client for Rust Documentation rust-ftp Installation Usage License Contribution Development environment Installation FTPS support is achie

Matt McCoy 155 Nov 12, 2022
NNTP client for Rust

rust-nntp NNTP Client for Rust Usage extern crate nntp; use nntp::{Article, NNTPStream}; fn main() { let mut nntp_stream = match NNTPStream::connec

Matt McCoy 13 Jan 22, 2022
POP3 client for Rust

rust-pop3 POP3 Client for Rust This client has SSL support. SSL is configured using an SSLContext that is passed into the connect method of a POP3Stre

Matt McCoy 26 Dec 19, 2022
A STOMP client in Rust. Compatible with RabbitMQ, ActiveMQ.

stomp-rs stomp-rs provides a full STOMP 1.2 client implementation for the Rust programming language. This allows programs written in Rust to interact

Zack Slayton 84 Dec 4, 2022
Rust client for NATS, the cloud native messaging system.

A Rust client for the NATS messaging system. Status Motivation Rust may be the most interesting new language the NATS ecosystem has seen. We believe t

NATS - The Cloud Native Messaging System 651 Jan 3, 2023
rqbit - bittorrent client in Rust

rqbit - bittorrent client in Rust

Igor Katson 177 Jan 2, 2023
Simple project to test grpc between ruby (client) and rust (server)

grpc-example Simple project to test grpc between ruby (client) and rust (server). Usage To simplify a lot this project uses docker and docker compose

Bruno Arueira 2 Oct 14, 2021
A rust client and structures to interact with the Clever-Cloud API.

Clever-Cloud Software Development Kit - Rust edition This crate provides structures and client to interact with the Clever-Cloud API. Status This crat

Clever Cloud 6 Jun 3, 2022
Third party Google DNS client for rust.

google-dns-rs Documentation Install Add the following line to your Cargo.toml file: google-dns-rs = "0.3.0" Usage use google_dns_rs::api::{Dns, DoH, R

Eduardo Stuart 2 Nov 13, 2021
Rust client for apache iotdb.

Apache IoTDB Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for data management and analysis, deployab

Mark Liu 7 Aug 4, 2022