# pushwire-client
Generic, multiplexed push client for real-time applications. Connects to a [pushwire-server](https://crates.io/crates/pushwire-server) instance over WebSocket or SSE.
Part of the [pushwire](https://crates.io/crates/pushwire) protocol family.
## Features
- **`PushClient<C>`** — generic over your `ChannelKind`, register per-channel receivers
- **WebSocket + SSE** — configurable transport preference with automatic fallback
- **Cursor tracking** — per-channel cursors with gap detection for reliable delivery
- **Auto-reconnect** — exponential backoff with jitter, configurable retry limits, cursor-based resume
- **Channel dispatch** — implement `ChannelReceiver` to handle frames per channel
- **Dynamic subscriptions** — subscribe/unsubscribe to channels after connect
## Quick start
```rust
use pushwire_client::{ChannelReceiver, ClientConfig, Frame, PushClient, ReconnectPolicy};
// Define MyChannel implementing ChannelKind (see pushwire-core)
struct ChatHandler;
impl ChannelReceiver<MyChannel> for ChatHandler {
fn on_frame(&self, frame: Frame<MyChannel>) {
println!("chat: {:?}", frame.payload);
}
}
let config = ClientConfig::new("http://127.0.0.1:9100");
let mut client = PushClient::<MyChannel>::new(config);
client.on(MyChannel::Chat, ChatHandler);
client.connect().await.unwrap();
// Send a frame
client.send(Frame::new(MyChannel::Chat, serde_json::json!({"msg": "hello"}))).await.unwrap();
// Graceful disconnect
client.disconnect().await.unwrap();
```
## Reconnect policy
```rust
use pushwire_client::ReconnectPolicy;
use std::time::Duration;
let policy = ReconnectPolicy {
enabled: true,
initial_delay: Duration::from_millis(100),
max_delay: Duration::from_secs(30),
backoff_factor: 2.0,
max_retries: Some(10),
jitter: true,
};
```
Set `ReconnectPolicy::disabled()` to turn off auto-reconnect.
## Feature flags
- **`rtc`** (default) — enables WebRTC signaling types via `pushwire-core/rtc`
## License
Apache-2.0