catcher_core 0.3.10
catcher_core: ^0.3.10 copied to clipboard
Resilient HTTP/WebSocket client backed by Rust core for Flutter
catcher_core #
Resilient HTTP/WebSocket client for Flutter — powered by a Rust core via dart:ffi. Part of the catcher toolkit.
Features #
- HTTP client — GET / POST / PUT / DELETE / PATCH via Rust reqwest
- WebSocket client — auto-reconnect, heartbeat, multi-endpoint racing
- Retry & circuit breaker — configurable resilience policies
- Connection pooling — keep-alive with configurable idle timeout
- DNS cache controls — cache size, TTL, stale fallback, nameservers, host mapping
- Transport MessagePack — optional native JSON ↔ msgpack conversion for HTTP and WS
- Binary codec — msgpack pack/unpack
- Network quality — evaluate connection health
Installation #
dependencies:
catcher_core: ^0.3.10
Note: The pub.dev package includes the native Rust libraries for supported platforms. If you build from a source checkout or need custom targets, see the Flutter manual build guide.
Quick Start #
HTTP Client #
import 'package:catcher_core/catcher_core.dart';
void main() async {
final client = CatcherHttpClient(HttpClientConfig(
baseUrl: 'https://api.example.com',
connectTimeoutMs: 5000,
responseTimeoutMs: 30000,
retry: RetryConfig(maxAttempts: 3, backoff: 'Fixed'),
pool: PoolConfig(keepAlive: true, maxIdlePerHost: 10),
dns: DnsConfig(
cacheSize: 512,
cacheTtlSecs: 300,
staleTtlSecs: 3600,
staleOnError: true,
hostMapping: {'api.internal': '10.0.0.10'},
),
msgpack: true,
));
// GET
final resp = await client.get('/channels');
print('Status: ${resp.status}, Body: ${resp.bodyAsString}');
// POST
final created = await client.post('/messages',
body: {'text': 'hello'},
contentType: 'application/json',
);
client.dispose();
}
WebSocket Client #
import 'package:catcher_core/catcher_core.dart';
void main() async {
final ws = CatcherWsClient(WsClientConfig(
urls: ['wss://echo.example.com'],
reconnect: WsReconnectConfig(initialDelayMs: 1000, maxDelayMs: 30000),
heartbeat: WsHeartbeatConfig(intervalMs: 30000, adaptive: true),
dns: DnsConfig(cacheTtlSecs: 300, staleOnError: true),
msgpack: true,
));
// Listen to events
ws.events.listen((event) {
if (event is WsConnectedEvent) {
print('Connected to ${event.url} (${event.latencyMs}ms)');
} else if (event is WsMessageEvent) {
print('Received: ${event.text}');
} else if (event is WsDisconnectedEvent) {
print('Disconnected: ${event.code} ${event.reason}');
} else if (event is WsReconnectingEvent) {
print('Reconnecting attempt ${event.attempt}');
} else if (event is WsHeartbeatRttEvent) {
print('Heartbeat RTT: ${event.rttMs}ms');
} else if (event is WsErrorEvent) {
print('Error: ${event.message}');
}
});
ws.sendText('{"event":"hello"}');
await Future.delayed(Duration(seconds: 5));
ws.dispose();
}
Binary Codec #
import 'package:catcher_core/catcher_core.dart';
final packed = pack({'event': 'ping', 'seq': 42}); // Uint8List (msgpack)
final unpacked = unpack(packed); // Map<String, dynamic>
DNS and MessagePack Config #
final config = HttpClientConfig(
baseUrl: 'https://api.example.com',
dns: DnsConfig(
cacheSize: 512,
cacheTtlSecs: 300,
negativeTtlSecs: 60,
staleTtlSecs: 3600,
staleOnError: true,
nameservers: ['8.8.8.8:53'],
hostMapping: {'api.internal': '10.0.0.10'},
),
msgpack: true,
);
API Reference #
HTTP #
| Type | Description |
|---|---|
CatcherHttpClient |
HTTP client wrapper (get, post, put, delete, patch) |
HttpClientConfig |
Base URL, timeouts, pool, retry, circuit breaker, dns, msgpack |
DnsConfig |
cacheSize, cacheTtlSecs, negativeTtlSecs, staleTtlSecs, staleOnError, nameservers, hostMapping |
HttpResponse |
status, headers, body bytes, elapsedMs, bodyAsString |
RetryConfig |
maxAttempts, backoff, jitter |
CircuitBreakerConfig |
failureThreshold, resetTimeoutMs |
PoolConfig |
keepAlive, maxIdlePerHost, idleTimeoutSecs |
CatcherHttpError |
Exception from Rust HTTP client |
WebSocket #
| Type | Description |
|---|---|
CatcherWsClient |
WebSocket client with event stream |
WsClientConfig |
URLs, reconnect, heartbeat, DNS, compression, msgpack |
WsReconnectConfig |
Reconnect timing (initial, max delay, backoff) |
WsHeartbeatConfig |
Heartbeat interval, adaptive, pong timeout |
WsEvent |
Base event class |
WsConnectedEvent |
url, latencyMs |
WsDisconnectedEvent |
code, reason |
WsReconnectingEvent |
attempt, delayMs |
WsMessageEvent |
data (bytes), isBinary, text getter |
WsErrorEvent |
message |
WsHeartbeatRttEvent |
rttMs |
CatcherWsError |
Exception from Rust WS client |
License #
MIT