{"id":29602076,"url":"https://github.com/joaquinbejar/lightstreamer-rs","last_synced_at":"2026-04-02T19:51:27.991Z","repository":{"id":293677233,"uuid":"984758063","full_name":"joaquinbejar/lightstreamer-rs","owner":"joaquinbejar","description":"Lightstreamer TLCP (Text-based Live Connections Protocol). It provides a robust client SDK to interact with Lightstreamer servers, enabling real-time data streaming for financial applications, IoT systems, and other use cases requiring live data updates. While it was initially developed to support the ig","archived":false,"fork":false,"pushed_at":"2025-06-17T08:43:25.000Z","size":255,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-18T20:10:11.510Z","etag":null,"topics":["lightstreamer","tlcp","trading","websocket"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joaquinbejar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-16T13:07:57.000Z","updated_at":"2025-06-29T14:37:56.000Z","dependencies_parsed_at":"2025-05-17T06:15:27.486Z","dependency_job_id":null,"html_url":"https://github.com/joaquinbejar/lightstreamer-rs","commit_stats":null,"previous_names":["joaquinbejar/lightstreamer-rs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/joaquinbejar/lightstreamer-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaquinbejar%2Flightstreamer-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaquinbejar%2Flightstreamer-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaquinbejar%2Flightstreamer-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaquinbejar%2Flightstreamer-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joaquinbejar","download_url":"https://codeload.github.com/joaquinbejar/lightstreamer-rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaquinbejar%2Flightstreamer-rs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266135070,"owners_count":23881776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lightstreamer","tlcp","trading","websocket"],"created_at":"2025-07-20T13:37:52.267Z","updated_at":"2026-04-02T19:51:27.958Z","avatar_url":"https://github.com/joaquinbejar.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv style=\"text-align: center;\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/joaquinbejar/lightstreamer-rs/refs/heads/main/doc/images/logo.png\" alt=\"lightstreamer-rs\" style=\"width: 100%; height: 100%;\"\u003e\n\u003c/div\u003e\n\n[![MIT License](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)\n[![Crates.io](https://img.shields.io/crates/v/lightstreamer-rs.svg)](https://crates.io/crates/lightstreamer-rs)\n[![Downloads](https://img.shields.io/crates/d/lightstreamer-rs.svg)](https://crates.io/crates/lightstreamer-rs)\n[![Stars](https://img.shields.io/github/stars/joaquinbejar/lightstreamer-rs.svg)](https://github.com/joaquinbejar/lightstreamer-rs/stargazers)\n[![Issues](https://img.shields.io/github/issues/joaquinbejar/lightstreamer-rs.svg)](https://github.com/joaquinbejar/lightstreamer-rs/issues)\n[![PRs](https://img.shields.io/github/issues-pr/joaquinbejar/lightstreamer-rs.svg)](https://github.com/joaquinbejar/lightstreamer-rs/pulls)\n[![Build Status](https://img.shields.io/github/workflow/status/joaquinbejar/lightstreamer-rs/CI)](https://github.com/joaquinbejar/lightstreamer-rs/actions)\n[![Coverage](https://img.shields.io/codecov/c/github/joaquinbejar/lightstreamer-rs)](https://codecov.io/gh/joaquinbejar/lightstreamer-rs)\n[![Dependencies](https://img.shields.io/librariesio/github/joaquinbejar/lightstreamer-rs)](https://libraries.io/github/joaquinbejar/lightstreamer-rs)\n[![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://docs.rs/lightstreamer-rs)\n[![Wiki](https://img.shields.io/badge/docs-latest-blue.svg)](https://deepwiki.com/joaquinbejar/lightstreamer-rs)\n\n\n## Lightstreamer Rust Client\n\nThis project is a Rust implementation of the Lightstreamer TLCP (Text-based Live Connections Protocol). It provides a robust client SDK to interact with Lightstreamer servers, enabling real-time data streaming for financial applications, IoT systems, and other use cases requiring live data updates. While it was initially developed to support the [ig_trading_api](https://github.com/joaquinbejar/ig_trading_api) project, it has evolved into a more comprehensive SDK with broader applicability.\n\n### Attribution\n\nThis project contains code derived from [lightstreamer-client](https://github.com/daniloaz/lightstreamer-client)\nby Daniel López Azaña (@daniloaz), originally published under GPL-3.0-only license in February 2024.\n\n### About Lightstreamer\n\nLightstreamer is a high-performance real-time messaging server that provides several key features:\n- Real-time data streaming with optimized bandwidth usage\n- Support for various transport mechanisms (WebSockets, HTTP streaming, etc.)\n- Different subscription modes for various data delivery patterns\n- Robust connection management with automatic recovery\n- Scalable architecture for high-volume applications\n\n### Features\n\nThis Rust client SDK provides the following capabilities:\n\n- **Connection Management**:\n  - Full-duplex WebSocket-based connection mode\n  - Automatic reconnection with configurable retry policies\n  - Session recovery after temporary disconnections\n  - Connection status monitoring and event notifications\n  - Proxy support for enterprise environments\n\n- **Subscription Capabilities**:\n  - Support for multiple subscription modes (MERGE, DISTINCT, COMMAND, RAW)\n  - Subscription to individual items or item groups\n  - Field schema definition for structured data\n  - Real-time item updates with change detection\n  - Snapshot support for initial state recovery\n\n- **Configuration Options**:\n  - Extensive connection options (polling intervals, timeouts, etc.)\n  - Bandwidth control and throttling\n  - Custom HTTP headers for authentication\n  - Logging configuration for debugging\n\n- **Event Handling**:\n  - Comprehensive event listener system\n  - Subscription lifecycle events (subscription, unsubscription)\n  - Item update notifications with field-level change detection\n  - Connection status change notifications\n  - Error handling and reporting\n\n### Implementation Status\n\nThe current implementation supports most core features of the Lightstreamer protocol, with a focus on the WebSocket transport mechanism and the MERGE subscription mode. While initially developed for specific trading API requirements, the library has expanded to include:\n\n- All subscription modes (MERGE, DISTINCT, COMMAND, RAW)\n- Robust error handling and recovery mechanisms\n- Comprehensive configuration options\n- Thread-safe asynchronous operation using Tokio\n\nSome advanced features that may be implemented in future versions include:\n\n- Message sending capabilities (MPN)\n- Client-side filtering and frequency limitations\n- Additional transport mechanisms beyond WebSockets\n- Enhanced security features\n\n### Installation\n\nTo use this SDK in your Rust project, add the following dependency to your `Cargo.toml`:\n\n```toml\n[dependencies]\nlightstreamer-rs = \"0.3.0\"\n```\n\n### Usage\n\n#### Quick Start (Simplified API)\n\nFor most use cases, use the simplified `SimpleClient` API:\n\n```rust\nuse lightstreamer_rs::client::{ClientConfig, SimpleClient, SubscriptionParams};\nuse lightstreamer_rs::subscription::SubscriptionMode;\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), lightstreamer_rs::utils::LightstreamerError\u003e {\n    // 1. Create configuration\n    let config = ClientConfig::new(\"http://push.lightstreamer.com/lightstreamer\")\n        .adapter_set(\"DEMO\");\n\n    // 2. Create client\n    let client = SimpleClient::new(config)?;\n\n    // 3. Subscribe and get channel receiver\n    let params = SubscriptionParams::new(\n        SubscriptionMode::Merge,\n        vec![\"item1\".to_string(), \"item2\".to_string()],\n        vec![\"last_price\".to_string(), \"time\".to_string()],\n    ).data_adapter(\"QUOTE_ADAPTER\");\n\n    let mut receiver = client.subscribe(params).await?;\n\n    // 4. Process updates asynchronously\n    tokio::spawn(async move {\n        while let Some(update) = receiver.recv().await {\n            println!(\"Price: {:?}\", update.get_value(\"last_price\"));\n        }\n    });\n\n    // 5. Connect and run\n    client.connect().await?;\n\n    Ok(())\n}\n```\n\n#### Advanced Usage (Full API)\n\nHere's a comprehensive example of how to use the Lightstreamer Rust Client SDK:\n\n```rust\n// This example shows how to use the Lightstreamer Rust client\nuse lightstreamer_rs::client::{LightstreamerClient, Transport};\nuse lightstreamer_rs::subscription::{Subscription, SubscriptionMode, SubscriptionListener, ItemUpdate};\nuse std::sync::Arc;\nuse tokio::sync::Notify;\nuse std::time::Duration;\n\n// Define a custom subscription listener\nstruct MySubscriptionListener;\n\nimpl SubscriptionListener for MySubscriptionListener {\n    fn on_subscription(\u0026self) {\n        info!(\"Subscription confirmed by the server\");\n    }\n\n    fn on_item_update(\u0026self, update: ItemUpdate) {\n        info!(\"Received update for item: {}\", update.get_item_name());\n        for field in update.get_fields() {\n            if let Some(value) = update.get_value(field) {\n                info!(\"  {} = {}\", field, value);\n            }\n        }\n    }\n}\n\nasync fn example() -\u003e Result\u003c(), Box\u003cdyn std::error::Error + Send + Sync\u003e\u003e {\n    // Create a new LightstreamerClient instance\n    let result = LightstreamerClient::new(\n        Some(\"ws://your-lightstreamer-server.com\"),  // Server address\n        Some(\"YOUR_ADAPTER_SET\"),                   // Adapter set\n        None,                                       // User (optional)\n        None,                                       // Password (optional)\n    );\n\n    let mut client = match result {\n        Ok(client) =\u003e client,\n        Err(e) =\u003e return Err(e),\n    };\n\n    // Configure the connection details if needed\n    client.connection_details.set_user(\"YOUR_USERNAME\");\n    client.connection_details.set_password(\"YOUR_PASSWORD\");\n\n    // Configure connection options if needed\n    client.connection_options.set_content_length(50000000);\n    client.connection_options.set_keepalive_interval(5);\n    client.connection_options.set_forced_transport(Some(Transport::WsStreaming));\n\n    // Create a shutdown signal for graceful termination\n    let shutdown_signal = Arc::new(Notify::new());\n\n    // Connect to the Lightstreamer server\n    if let Err(e) = client.connect(shutdown_signal.clone()).await {\n        return Err(e);\n    }\n\n    // Create a subscription\n    let subscription_result = Subscription::new(\n        SubscriptionMode::Merge,\n        Some(vec![\"item1\".to_string(), \"item2\".to_string()]),\n        Some(vec![\"field1\".to_string(), \"field2\".to_string()]),\n    );\n\n    let subscription = match subscription_result {\n        Ok(sub) =\u003e sub,\n        Err(e) =\u003e return Err(e),\n    };\n\n    // Add a listener to the subscription (optional)\n    let listener = Box::new(MySubscriptionListener);\n    subscription.add_listener(listener);\n\n    // Get the subscription sender from the client\n    // Note: This method might not exist in the current API, check the documentation\n    let subscription_sender = client.get_subscriptions()[0].clone();\n\n    // Subscribe and get the subscription ID\n    let subscription_id_result = LightstreamerClient::subscribe_get_id(\n        subscription_sender.clone(),\n        subscription\n    ).await;\n\n    let subscription_id = match subscription_id_result {\n        Ok(id) =\u003e id,\n        Err(e) =\u003e return Err(e),\n    };\n\n    info!(\"Subscribed with ID: {}\", subscription_id);\n\n    // Wait for some time (in a real application, you would wait for a shutdown signal)\n    tokio::time::sleep(Duration::from_secs(5)).await;\n\n    // Unsubscribe before disconnecting\n    LightstreamerClient::unsubscribe(subscription_sender, subscription_id).await;\n\n    Ok(())\n}\n```\n\n#### Handling Client Events\n\nYou can also add listeners to handle client events:\n\nHere's an example of implementing a client listener:\n\n```rust\n// Note: ClientListener is a private trait, this is just for illustration\nuse lightstreamer_rs::client::model::ClientStatus;\n\nstruct MyClientListener;\n\n// This is just an example of what the ClientListener trait might look like\n// The actual implementation is internal to the library\ntrait ClientListener {\n    fn on_status_change(\u0026self, status: \u0026ClientStatus);\n    fn on_server_error(\u0026self, error_code: i32, error_message: \u0026str);\n    fn on_property_change(\u0026self, property: \u0026str);\n}\n\nimpl ClientListener for MyClientListener {\n    fn on_status_change(\u0026self, status: \u0026ClientStatus) {\n        info!(\"Client status changed to: {:?}\", status);\n    }\n\n    fn on_server_error(\u0026self, error_code: i32, error_message: \u0026str) {\n        info!(\"Server error: {} - {}\", error_code, error_message);\n    }\n\n    fn on_property_change(\u0026self, property: \u0026str) {\n        info!(\"Property changed: {}\", property);\n    }\n}\n\n// Then add the listener to your client\n// client.add_listener(Box::new(MyClientListener));\n```\n\n#### Channel-Based Update Processing\n\nFor asynchronous processing of updates in separate tasks, you can use the `ChannelSubscriptionListener`:\n\n```rust\nuse lightstreamer_rs::subscription::ChannelSubscriptionListener;\n\n// Create a channel-based listener\nlet (listener, mut update_receiver) = ChannelSubscriptionListener::create_channel();\n\n// Add the listener to your subscription\nsubscription.add_listener(Box::new(listener));\n\n// Process updates asynchronously in a separate task\ntokio::spawn(async move {\n    while let Some(update) = update_receiver.recv().await {\n        // Process the update\n        println!(\"Item: {:?}\", update.get_item_name());\n        println!(\"Fields: {:?}\", update.get_fields());\n\n        // Perform any async operations\n        // e.g., save to database, send to another service, etc.\n    }\n});\n```\n\nThis approach allows you to:\n- Decouple update reception from processing\n- Process updates asynchronously without blocking the Lightstreamer event loop\n- Easily integrate with other async workflows\n- Handle backpressure naturally through channel buffering\n\n\n\n\n## Contribution and Contact\n\nWe welcome contributions to this project! If you would like to contribute, please follow these steps:\n\n1. Fork the repository.\n2. Create a new branch for your feature or bug fix.\n3. Make your changes and ensure that the project still builds and all tests pass.\n4. Commit your changes and push your branch to your forked repository.\n5. Submit a pull request to the main repository.\n\nIf you have any questions, issues, or would like to provide feedback, please feel free to contact the project maintainer:\n\n**Joaquín Béjar García**\n- Email: jb@taunais.com\n- GitHub: [joaquinbejar](https://github.com/joaquinbejar)\n\nWe appreciate your interest and look forward to your contributions!\n\n## ✍️ License\n\nLicensed under GPL-3.0 license\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoaquinbejar%2Flightstreamer-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoaquinbejar%2Flightstreamer-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoaquinbejar%2Flightstreamer-rs/lists"}