# 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: ```bash git clone https://github.com/samespace/rspub.git cd rspub ``` 2. Build the project: ```bash cargo build --release ``` ### Using Cargo ```bash cargo install rspub ``` ## Quick Start 1. Create a configuration file `config.yaml`: ```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" ``` 2. Generate TLS certificates: ```bash rspub cert-gen --cert cert.pem --key key.pem ``` 3. Start the server: ```bash rspub start --config config.yaml ``` ## Usage ### Command Line Interface ```bash # 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 ```rust 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 ```bash 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 ```bash # 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](LICENSE) file for details. ## Acknowledgments - [Quinn](https://github.com/quinn-rs/quinn) - QUIC protocol implementation - [Tokio](https://tokio.rs) - Async runtime - [Rustls](https://github.com/rustls/rustls) - TLS library ## Roadmap - [ ] Clustering support - [ ] Message persistence - [ ] WebSocket bridge - [ ] Prometheus metrics - [ ] Admin dashboard - [ ] Plugin system ## Support - Documentation: [docs.rs/rspub](https://docs.rs/rspub) - Issues: [GitHub Issues](https://github.com/yourusername/rspub/issues) - Discord: [Join our community](https://discord.gg/yourdiscord)