#quic #pub-sub #message #pattern #tls #messaging #transport

bin+lib rsub

A high-performance message broker with QUIC transport and pub/sub messaging patterns

1 unstable release

0.1.0 Nov 22, 2024

#163 in Authentication

Download history 95/week @ 2024-11-16 52/week @ 2024-11-23 5/week @ 2024-11-30 6/week @ 2024-12-07

158 downloads per month

Apache-2.0

59KB
1K SLoC

RSPub

RSPub is a high-performance publish/subscribe (pub/sub) messaging system built in Rust using the QUIC protocol. It provides secure, reliable, and efficient message delivery with support for multiple authentication methods.

Features

  • 🚀 High-performance QUIC Transport - Built on Quinn, a pure-rust QUIC implementation
  • 🔒 Built-in Security - TLS 1.3 encryption by default
  • 🔑 Flexible Authentication - Support for Basic and Bearer authentication
  • 📨 Pub/Sub Messaging - Topic-based publish/subscribe patterns
  • 🔄 Bi-directional Streaming - Full duplex communication
  • 📦 Binary Message Support - Efficient binary message format
  • Async First - Built on Tokio for maximum performance
  • 🛠️ YAML Configuration - Simple and flexible configuration

Installation

From Source

  1. Clone the repository:
git clone https://github.com/samespace/rspub.git
cd rspub
  1. Build the project:
cargo build --release

Using Cargo

cargo install rspub

Quick Start

  1. Create a configuration file config.yaml:
server:
  host: "127.0.0.1"
  port: 4222
  max_payload: 1048576  # 1 MB
  max_connections: 1000

auth:
  type: Basic
  config:
    username: admin
    password: secret

tls:
  enabled: true
  cert_file: "cert.pem"
  key_file: "key.pem"
  1. Generate TLS certificates:
rspub cert-gen --cert cert.pem --key key.pem
  1. Start the server:
rspub start --config config.yaml

Usage

Command Line Interface

# Start the server
rspub start --config config.yaml

# Subscribe to a topic
rspub sub my-topic --server localhost:4222

# Publish to a topic
rspub pub my-topic "Hello World" --server localhost:4222

As a Library

use rspub::client::client::RsubClient;
use rspub::common::auth::{AuthConfig, AuthType, BasicAuth};

#[tokio::main]
async fn main() {
    // Connect to RSub server
    let client = RsubClient::connect(
        "127.0.0.1:4222".parse().unwrap(),
        "cert.pem",
        AuthConfig::new(AuthType::Basic(BasicAuth {
            username: "admin".to_string(),
            password: "secret".to_string(),
        })),
    ).await.unwrap();

    // Subscribe to topics
    client.subscribe(vec!["my-topic".to_string()], |message| {
        println!("Received: {:?}", message);
    }).await.unwrap();

    // Publish messages
    client.publish(
        vec!["my-topic".to_string()],
        "Hello RSub!".into()
    ).await.unwrap();
}

Configuration

RSub can be configured using a YAML file. Here are the available options:

Option Description Default
server.host Server host address "127.0.0.1"
server.port Server port 4222
server.max_payload Maximum message size in bytes 1MB
server.max_connections Maximum concurrent connections 1000
tls.enabled Enable TLS encryption false
tls.cert_file TLS certificate file path -
tls.key_file TLS private key file path -
auth.type Authentication type (Basic/Bearer) None

Performance

RSub is designed for high performance:

  • Low Latency: Sub-millisecond message delivery
  • High Throughput: Capable of handling millions of messages per second
  • Efficient Resource Usage: Low memory and CPU footprint
  • Connection Scaling: Supports thousands of concurrent connections

Message Format

RSPub uses a binary message format (wire format) to achieve maximum performance.

The message format consists of the following fields:

+-------------------+-------------------+-------------------+-------------------+
| Message Type (1B) | Topics count (1B) | Topic 1 length(1B)| Topic 1 string    |
+-------------------+-------------------+-------------------+-------------------+
| Topic 2 length(1B)| Topic 2 string    | ...               | Data length (4B)  |
+-------------------+-------------------+-------------------+-------------------+
| Data              |
+-------------------+

Example message with topic "sensors.temp" and payload "23.5":

00000000  01 01 0B 73 65 6E 73 6F  72 73 2E 74 65 6D 70 03  |...sensors.temp.|
00000010  32 33 2E 35                                       |23.5|

Breakdown:
01       -> Message Type = Message (1)
01       -> Topics Count = 1
0B       -> Topic 1 Length = 11 bytes ("sensors/temp")
73...70  -> Topic 1 String = "sensors/temp"
00000003 -> Data Length = 3 bytes
32 33 35 -> Data = "23.5"
  1. Message Type (1 byte):

    • Indicates the type of message:
      • Auth (0): Authentication messages
      • Message (1): Regular pub/sub messages
      • Subscribe (2): Topic subscription requests
      • Response (3): Server responses
    • Single byte allows fast parsing while supporting key message types
  2. Topics Count (1 byte):

    • Number of topics (0-255)
    • Compact representation for typical use cases
    • Allows efficient multi-topic messages
  3. Topic Fields (variable):

    • For each topic:
      • Length prefix (1 byte)
      • UTF-8 encoded topic string
    • Length-prefixed format enables zero-copy parsing
    • Supports hierarchical topic structures
  4. Data Length (4 bytes):

    • Size of payload in bytes
    • Supports messages up to 4GB
    • Enables pre-allocation of receive buffers
  5. Data (variable):

    • Raw message payload
    • Format agnostic (can contain any binary data)

Advantages

  • Compact: Minimal overhead compared to text formats like JSON
  • Fast Parsing: Fixed-size headers enable efficient parsing
  • Zero Copy: Length-prefixed fields allow zero-copy operations
  • Flexible: Supports variable-length topics and payloads
  • Self-Describing: Includes all necessary length information
  • Forward Compatible: Reserved bits allow format evolution
  • Language Agnostic: Simple binary format works across platforms

Security

RSub uses TLS 1.3 for transport security and supports multiple authentication methods. It's recommended to:

  1. Always enable TLS in production
  2. Use strong passwords for Basic authentication
  3. Regularly rotate Bearer tokens
  4. Keep certificates up to date

Generate TLS Certificates

rspub cert-gen --cert cert.pem --key key.pem

Authentication Methods

  • Basic Auth: Username/password authentication
  • Bearer Token: JWT token-based authentication
  • Custom Auth: Implement your own authentication provider

Contributing

Contributions are welcome! Please feel free to submit pull requests.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Install development dependencies
cargo install cargo-watch cargo-tarpaulin

# Run tests
cargo test

# Run with hot reload
cargo watch -x run

# Generate code coverage
cargo tarpaulin

Troubleshooting

Common issues and solutions:

  1. Connection Refused: Ensure the server is running and the port is accessible
  2. Authentication Failed: Verify credentials in config.yaml
  3. TLS Errors: Check certificate paths and validity
  4. Performance Issues: Adjust max_payload and max_connections settings

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Quinn - QUIC protocol implementation
  • Tokio - Async runtime
  • Rustls - TLS library

Roadmap

  • Clustering support
  • Message persistence
  • WebSocket bridge
  • Prometheus metrics
  • Admin dashboard
  • Plugin system

Support

Dependencies

~18–28MB
~521K SLoC