seedlink-rs-protocol 0.3.1

SeedLink protocol types, commands, and frame parsing
Documentation

seedlink-rs

Pure Rust SeedLink client and server. Zero unsafe, zero C dependency.

Crates.io docs.rs CI License Rust

Sister project of miniseed-rs.

Crates

Crate Description
seedlink-rs-protocol SeedLink protocol types, commands, and frame parsing
seedlink-rs-client Async SeedLink client (tokio)
seedlink-rs-server Async SeedLink server (tokio)

Quick Start — Client

use seedlink_rs_client::SeedLinkClient;

#[tokio::main]
async fn main() -> seedlink_rs_client::Result<()> {
    let mut client = SeedLinkClient::connect("rtserve.iris.washington.edu:18000").await?;
    client.station("ANMO", "IU").await?;
    client.select("BHZ").await?;
    client.data().await?;
    client.end_stream().await?;

    while let Some(frame) = client.next_frame().await? {
        println!("seq={}, payload={} bytes", frame.sequence(), frame.payload().len());
    }
    Ok(())
}

Quick Start — Server

use seedlink_rs_server::SeedLinkServer;

#[tokio::main]
async fn main() -> seedlink_rs_server::Result<()> {
    let server = SeedLinkServer::bind("0.0.0.0:18000").await?;
    let store = server.store().clone();

    tokio::spawn(server.run());

    // Push miniSEED records from any source
    let payload = vec![0u8; 512];
    store.push("IU", "ANMO", &payload);
    Ok(())
}

Features

Protocol (seedlink-rs-protocol)

  • Full SeedLink v3 and v4 command parsing and serialization (14 commands)
  • v3 fixed frames (520 bytes) and v4 variable-length frames
  • Sequence numbers: v3 hex (24-bit) and v4 decimal (64-bit)
  • Response parsing with error codes
  • INFO levels: ID, STATIONS, STREAMS, CONNECTIONS, and more
  • Version-aware validation — prevents sending v3-only commands on v4

Client (seedlink-rs-client)

  • Async TCP client with state machine enforcement
  • Automatic v4 protocol negotiation (falls back to v3)
  • Station/channel selection with SELECT pattern filtering
  • TIME command for time-windowed data requests
  • DATA resume from last sequence number
  • FETCH mode — stream buffered data then close
  • futures::Stream impl via into_stream()
  • Auto-reconnect with exponential backoff and per-station sequence resume
  • Built-in deduplication — no duplicate frames after reconnect
  • miniSEED decode via miniseed-rs
  • tracing integration for structured logging
  • Configurable connect and read timeouts

Server (seedlink-rs-server)

  • Async TCP server — multiple concurrent clients
  • In-memory ring buffer with configurable capacity
  • Dual protocol: v3 and v4 frame streaming (auto-adapts per client)
  • Multi-station subscription per client
  • SELECT pattern filtering with ? wildcards (BHZ, BH?, 00BHZ.D)
  • TIME filtering — parses miniSEED BTime, filters by time window
  • INFO responses: ID, STATIONS, STREAMS, CONNECTIONS (XML)
  • Connection tracking — protocol version, user agent, state
  • USERAGENT and BATCH command support
  • FETCH mode — send buffered data then close
  • Graceful shutdown via ShutdownHandle

Compatibility

Tested against real SeedLink servers:

  • IRIS: rtserve.iris.washington.edu:18000
  • GEOFON: geofon.gfz-potsdam.de:18000

219 tests passing across all three crates.

Benchmarks

Server fan-out stress test on localhost (loopback TCP). The traditional C-based SeedLink servers (ringserver, SeisComP seedlink) use thread-per-connection with blocking I/O. seedlink-rs uses async I/O (tokio/epoll) — delivering 10.7 million frames/sec aggregate to 100 concurrent clients with zero frame loss.

                        Ingestion                    Fan-out delivery
                        ─────────►                   ─────────────────►
Data source ──► [ Server ring buffer ] ──► Client 1   (10,000 frames)
                    34K rec/s              Client 2   (10,000 frames)
                                           ...
                                           Client 100 (10,000 frames)
                                           ─────────────────────────────
                                           Total: 1,000,000 frames
                                           in 0.094s = 10.7M frames/s

Each record is one 512-byte miniSEED packet. One record pushed = one frame delivered per subscribed client.

Scenario Clients Records Pushed Ingestion Rate Per-Client Delivery Aggregate Output Correctness
Default 50 10,000 47K rec/s 48K frames/s 2.4M frames/s 100%
High 100 10,000 34K rec/s 107K frames/s 10.7M frames/s 100%

Run cargo run --example stress_test -p seedlink-rs-server --release to reproduce. Configurable via env vars: CLIENTS, RECORDS, RING_CAP.

Platform: AMD Ryzen 5 5600G (6C/12T, 4.46 GHz), 16 GB DDR4, Linux 6.17, rustc 1.92.0, --release

Documentation

See docs/FEATURES.md for comprehensive feature documentation.

License

Apache-2.0