# MIP-Client-rust
[](https://crates.io/crates/mip-client)
[](https://docs.rs/mip-client)
[](https://opensource.org/licenses/MIT)
Rust client for the MIP (MSIP) protocol with async support.
**Server implementation:** [MIP Server](https://github.com/DoctorPok42/MIP)
**Part of the MIP Client family:**
- TypeScript: [@mip-client/ts](https://www.npmjs.com/package/@mip-client/ts)
- Python: [mip-client-python](https://pypi.org/project/mip-client-python/)
- Rust: [mip-client](https://crates.io/crates/mip-client) (this package)
## Features
- **Async/Await** - Built on Tokio for high-performance async I/O
- **Auto-reconnection** - Automatic reconnection with configurable retry logic
- **Event-driven** - Callback-based API for handling messages and events
- **Type-safe** - Full Rust type safety with proper error handling
- **Ping/Pong** - Configurable heartbeat interval
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
mip-client = "1.0"
tokio = { version = "1", features = ["full"] }
```
Or via cargo:
```bash
cargo add mip-client
```
## Quick Start
```rust
use mip_client::{MIPClient, MIPClientOptions, FrameFlags};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let options = MIPClientOptions::default()
.client_id("my_client_123") // Optional client identifier
.host("127.0.0.1")
.port(9000)
.auto_reconnect(true);
let mut client = MIPClient::new(options);
client.on_connect(|| {
println!("Connected!");
});
client.on_message(|msg| {
println!("Received: {} - {}", msg.topic, msg.message);
});
client.on_error(|err| {
eprintln!("Error: {}", err);
});
client.connect().await?;
client.subscribe("my/topic", true)?;
client.publish("my/topic", "Hello!", FrameFlags::NONE)?;
tokio::signal::ctrl_c().await?;
client.disconnect().await?;
Ok(())
}
```
## API Reference
### MIPClientOptions
| `client_id` | String | "" | Client identifier (sent in HELLO frame) |
| `host` | String | "127.0.0.1" | Server host address |
| `port` | u16 | 9000 | Server port number |
| `auto_reconnect` | bool | true | Auto-reconnect on disconnect |
| `reconnect_delay_ms` | u64 | 3000 | Reconnect delay in ms |
| `max_reconnect_attempts` | u32 | 10 | Max reconnect attempts (0 = infinite) |
| `ping_interval_ms` | u64 | 0 | Ping interval in ms (0 = disabled) |
### Methods
| `connect()` | Connect to the MIP server |
| `disconnect()` | Disconnect from the server |
| `subscribe(topic, require_ack)` | Subscribe to a topic |
| `unsubscribe(topic, require_ack)` | Unsubscribe from a topic |
| `publish(topic, message, flags)` | Publish a message to a topic |
| `ping()` | Send a ping to the server |
| `is_connected()` | Check if the client is connected |
### Events
| `on_connect` | `Fn()` | Called when connected |
| `on_disconnect` | `Fn()` | Called when disconnected |
| `on_reconnecting` | `Fn(u32)` | Called on reconnection attempt |
| `on_message` | `Fn(MIPMessage)` | Called on any message |
| `on_event` | `Fn(MIPMessage)` | Called on EVENT frames |
| `on_ack` | `Fn(u64)` | Called when ACK received |
| `on_pong` | `Fn()` | Called when PONG received |
| `on_error` | `Fn(MIPError)` | Called on error |
| `on_frame` | `Fn(Header, Vec<u8>)` | Called on any raw frame |
### Frame Flags
```rust
use mip_client::FrameFlags;
FrameFlags::NONE // No flags
FrameFlags::ACK_REQUIRED // Request acknowledgment
FrameFlags::COMPRESSED // Payload is compressed
FrameFlags::URGENT // Urgent message
```
## Protocol
The MIP protocol uses a binary frame format with a 24-byte header:
| Magic | 4 bytes | "MSIP" |
| Version | 1 byte | Protocol version (1) |
| Flags | 1 byte | Frame flags |
| Frame Type | 2 bytes | Type of frame |
| Message Kind | 2 bytes | Kind of message |
| Reserved | 2 bytes | Reserved for future use |
| Payload Length | 4 bytes | Length of payload |
| Message ID | 8 bytes | Unique message identifier |
## License
MIT