oxigdal-ws 0.1.3

WebSocket streaming support for OxiGDAL - real-time geospatial data delivery
Documentation
# OxiGDAL-WS: WebSocket Streaming for Real-time Geospatial Data

[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/cool-japan/oxigdal/blob/main/LICENSE)
[![Pure Rust](https://img.shields.io/badge/Pure-Rust-orange.svg)](https://www.rust-lang.org/)

WebSocket streaming support for OxiGDAL, enabling real-time delivery of geospatial data to web and mobile applications.

## Features

- **WebSocket Server**: High-performance Axum-based server with connection management
- **WebSocket Client**: Async client with automatic reconnection support
- **Multiple Protocols**: JSON, MessagePack, and Binary formats with Zstandard compression
- **Tile Streaming**: Real-time map tile delivery with delta encoding
- **Feature Streaming**: GeoJSON feature updates with change detection
- **Event Streaming**: System events, progress updates, and notifications
- **Subscription Management**: Spatial, temporal, and attribute-based filtering
- **Backpressure Control**: Automatic throttling and flow control

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
oxigdal-ws = "0.1"
```

## Usage

### Server

```rust
use oxigdal_ws::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    let server = WebSocketServer::builder()
        .bind("0.0.0.0:9001")?
        .max_connections(10000)
        .default_format(MessageFormat::MessagePack)
        .default_compression(Compression::Zstd)
        .enable_cors(true)
        .build();

    server.run().await?;
    Ok(())
}
```

### Client (Rust)

```rust
use oxigdal_ws::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    // Connect to server
    let mut client = WebSocketClient::connect("ws://localhost:9001/ws").await?;

    // Subscribe to tiles in San Francisco
    let sub_id = client.subscribe_tiles(
        [-122.5, 37.5, -122.0, 38.0],  // bbox
        10..14  // zoom range
    ).await?;

    // Get tile stream
    let mut tiles = client.tile_stream();
    while let Some(tile) = tiles.next_tile().await {
        println!("Received tile: {:?} ({} bytes)",
                 tile.coords(), tile.size());
        // Process tile...
    }

    Ok(())
}
```

### Client (JavaScript)

```javascript
const ws = new WebSocket('ws://localhost:9001/ws');

// Subscribe to viewport
ws.send(JSON.stringify({
    type: 'subscribe_tiles',
    subscription_id: 'my-subscription',
    bbox: [-122.5, 37.5, -122.0, 38.0],
    zoom_range: { start: 10, end: 14 },
    tile_size: 256
}));

// Receive tiles
ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'tile_data') {
        console.log('Received tile:', data.tile);
        renderTile(data);
    }
};
```

## Features Streaming

```rust
// Subscribe to feature updates
let sub_id = client.subscribe_features(Some("buildings".to_string())).await?;

// Get feature stream
let mut features = client.feature_stream();
while let Some(feature) = features.next_feature().await {
    match feature.change_type {
        ChangeType::Added => println!("New feature: {}", feature.geojson),
        ChangeType::Updated => println!("Updated feature: {}", feature.geojson),
        ChangeType::Deleted => println!("Deleted feature"),
    }
}
```

## Event Streaming

```rust
// Subscribe to events
let sub_id = client.subscribe_events(vec![
    EventType::FileChange,
    EventType::Progress,
    EventType::ProcessingStatus,
]).await?;

// Get event stream
let mut events = client.event_stream();
while let Some(event) = events.next_event().await {
    println!("Event: {:?} - {:?}", event.event_type, event.payload);
}
```

## Protocol Formats

### JSON (Human-readable)

```json
{
  "type": "subscribe_tiles",
  "subscription_id": "sub-123",
  "bbox": [-180, -90, 180, 90],
  "zoom_range": { "start": 0, "end": 14 },
  "tile_size": 256
}
```

### MessagePack (Efficient, default)

Compact binary format, typically 30-50% smaller than JSON.

### Binary with Zstandard Compression

Maximum efficiency for large data transfers, typically 60-80% size reduction.

## Use Cases

- **Real-time satellite imagery delivery**: Stream newly acquired imagery as it becomes available
- **Live tracking applications**: Update vehicle/asset positions in real-time
- **Collaborative editing**: Synchronize edits across multiple users
- **Change monitoring**: Detect and stream environmental changes as they occur
- **Streaming analytics**: Deliver analysis results progressively
- **Live sensor data**: Stream real-time IoT sensor readings

## Architecture

```
┌─────────────┐     WebSocket      ┌─────────────┐
│   Clients   │ ◄────────────────► │   Server    │
│             │                     │             │
│  Browser    │  Subscribe Tiles   │ Tile Handler│
│  Mobile App │  Subscribe Features│Feature Hdlr │
│  Desktop    │  Subscribe Events  │Event Handler│
└─────────────┘                     └─────────────┘
                                    ┌──────▼──────┐
                                    │ OxiGDAL Core│
                                    │   Dataset   │
                                    │  Processing │
                                    └─────────────┘
```

## Performance

- **Connections**: Supports 10,000+ concurrent WebSocket connections
- **Throughput**: Up to 1 GB/s tile streaming (with delta encoding)
- **Latency**: <10ms message round-trip time (localhost)
- **Compression**: 60-80% size reduction with Zstandard
- **Delta Encoding**: 70-90% bandwidth savings for tile updates

## Pure Rust

OxiGDAL-WS is 100% Pure Rust with no C/C++ dependencies, ensuring memory safety and cross-platform compatibility.

## License

Licensed under the Apache License, Version 2.0. See [LICENSE](../../LICENSE) for details.

## Contributing

Contributions welcome! Please see [CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines.

## Authors

Copyright © 2026 COOLJAPAN OU (Team Kitasan)