lightstreamer_rs/lib.rs
1//! # Lightstreamer Rust Client
2//!
3//! This 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.
4//!
5//! ## About Lightstreamer
6//!
7//! Lightstreamer is a high-performance real-time messaging server that provides several key features:
8//! - Real-time data streaming with optimized bandwidth usage
9//! - Support for various transport mechanisms (WebSockets, HTTP streaming, etc.)
10//! - Different subscription modes for various data delivery patterns
11//! - Robust connection management with automatic recovery
12//! - Scalable architecture for high-volume applications
13//!
14//! ## Features
15//!
16//! This Rust client SDK provides the following capabilities:
17//!
18//! - **Connection Management**:
19//! - Full-duplex WebSocket-based connection mode
20//! - Automatic reconnection with configurable retry policies
21//! - Session recovery after temporary disconnections
22//! - Connection status monitoring and event notifications
23//! - Proxy support for enterprise environments
24//!
25//! - **Subscription Capabilities**:
26//! - Support for multiple subscription modes (MERGE, DISTINCT, COMMAND, RAW)
27//! - Subscription to individual items or item groups
28//! - Field schema definition for structured data
29//! - Real-time item updates with change detection
30//! - Snapshot support for initial state recovery
31//!
32//! - **Configuration Options**:
33//! - Extensive connection options (polling intervals, timeouts, etc.)
34//! - Bandwidth control and throttling
35//! - Custom HTTP headers for authentication
36//! - Logging configuration for debugging
37//!
38//! - **Event Handling**:
39//! - Comprehensive event listener system
40//! - Subscription lifecycle events (subscription, unsubscription)
41//! - Item update notifications with field-level change detection
42//! - Connection status change notifications
43//! - Error handling and reporting
44//!
45//! ## Implementation Status
46//!
47//! The 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:
48//!
49//! - All subscription modes (MERGE, DISTINCT, COMMAND, RAW)
50//! - Robust error handling and recovery mechanisms
51//! - Comprehensive configuration options
52//! - Thread-safe asynchronous operation using Tokio
53//!
54//! Some advanced features that may be implemented in future versions include:
55//!
56//! - Message sending capabilities (MPN)
57//! - Client-side filtering and frequency limitations
58//! - Additional transport mechanisms beyond WebSockets
59//! - Enhanced security features
60//!
61//! ## Installation
62//!
63//! To use this SDK in your Rust project, add the following dependency to your `Cargo.toml`:
64//!
65//! ```toml
66//! [dependencies]
67//! lightstreamer-rs = "0.1.4"
68//! ```
69//!
70//! ## Usage
71//!
72//! Here's a comprehensive example of how to use the Lightstreamer Rust Client SDK:
73//!
74//! ```ignore
75//! // This example shows how to use the Lightstreamer Rust client
76//! use lightstreamer_rs::client::{LightstreamerClient, Transport};
77//! use lightstreamer_rs::subscription::{Subscription, SubscriptionMode, SubscriptionListener, ItemUpdate};
78//! use std::sync::Arc;
79//! use tokio::sync::Notify;
80//! use std::time::Duration;
81//!
82//! // Define a custom subscription listener
83//! struct MySubscriptionListener;
84//!
85//! impl SubscriptionListener for MySubscriptionListener {
86//! fn on_subscription(&self) {
87//! info!("Subscription confirmed by the server");
88//! }
89//!
90//! fn on_item_update(&self, update: ItemUpdate) {
91//! info!("Received update for item: {}", update.get_item_name());
92//! for field in update.get_fields() {
93//! if let Some(value) = update.get_value(field) {
94//! info!(" {} = {}", field, value);
95//! }
96//! }
97//! }
98//! }
99//!
100//! async fn example() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
101//! // Create a new LightstreamerClient instance
102//! let result = LightstreamerClient::new(
103//! Some("ws://your-lightstreamer-server.com"), // Server address
104//! Some("YOUR_ADAPTER_SET"), // Adapter set
105//! None, // User (optional)
106//! None, // Password (optional)
107//! );
108//!
109//! let mut client = match result {
110//! Ok(client) => client,
111//! Err(e) => return Err(e),
112//! };
113//!
114//! // Configure the connection details if needed
115//! client.connection_details.set_user("YOUR_USERNAME");
116//! client.connection_details.set_password("YOUR_PASSWORD");
117//!
118//! // Configure connection options if needed
119//! client.connection_options.set_content_length(50000000);
120//! client.connection_options.set_keepalive_interval(5);
121//! client.connection_options.set_forced_transport(Some(Transport::WsStreaming));
122//!
123//! // Create a shutdown signal for graceful termination
124//! let shutdown_signal = Arc::new(Notify::new());
125//!
126//! // Connect to the Lightstreamer server
127//! if let Err(e) = client.connect(shutdown_signal.clone()).await {
128//! return Err(e);
129//! }
130//!
131//! // Create a subscription
132//! let subscription_result = Subscription::new(
133//! SubscriptionMode::Merge,
134//! Some(vec!["item1".to_string(), "item2".to_string()]),
135//! Some(vec!["field1".to_string(), "field2".to_string()]),
136//! );
137//!
138//! let subscription = match subscription_result {
139//! Ok(sub) => sub,
140//! Err(e) => return Err(e),
141//! };
142//!
143//! // Add a listener to the subscription (optional)
144//! let listener = Box::new(MySubscriptionListener);
145//! subscription.add_listener(listener);
146//!
147//! // Get the subscription sender from the client
148//! // Note: This method might not exist in the current API, check the documentation
149//! let subscription_sender = client.get_subscriptions()[0].clone();
150//!
151//! // Subscribe and get the subscription ID
152//! let subscription_id_result = LightstreamerClient::subscribe_get_id(
153//! subscription_sender.clone(),
154//! subscription
155//! ).await;
156//!
157//! let subscription_id = match subscription_id_result {
158//! Ok(id) => id,
159//! Err(e) => return Err(e),
160//! };
161//!
162//! info!("Subscribed with ID: {}", subscription_id);
163//!
164//! // Wait for some time (in a real application, you would wait for a shutdown signal)
165//! tokio::time::sleep(Duration::from_secs(5)).await;
166//!
167//! // Unsubscribe before disconnecting
168//! LightstreamerClient::unsubscribe(subscription_sender, subscription_id).await;
169//!
170//! Ok(())
171//! }
172//! ```
173//!
174//! ### Handling Client Events
175//!
176//! You can also add listeners to handle client events:
177//!
178//! Here's an example of implementing a client listener:
179//!
180//! ```ignore
181//! // Note: ClientListener is a private trait, this is just for illustration
182//! use lightstreamer_rs::client::model::ClientStatus;
183//!
184//! struct MyClientListener;
185//!
186//! // This is just an example of what the ClientListener trait might look like
187//! // The actual implementation is internal to the library
188//! trait ClientListener {
189//! fn on_status_change(&self, status: &ClientStatus);
190//! fn on_server_error(&self, error_code: i32, error_message: &str);
191//! fn on_property_change(&self, property: &str);
192//! }
193//!
194//! impl ClientListener for MyClientListener {
195//! fn on_status_change(&self, status: &ClientStatus) {
196//! info!("Client status changed to: {:?}", status);
197//! }
198//!
199//! fn on_server_error(&self, error_code: i32, error_message: &str) {
200//! info!("Server error: {} - {}", error_code, error_message);
201//! }
202//!
203//! fn on_property_change(&self, property: &str) {
204//! info!("Property changed: {}", property);
205//! }
206//! }
207//!
208//! // Then add the listener to your client
209//! // client.add_listener(Box::new(MyClientListener));
210//! ```
211//!
212
213/// Module containing subscription-related functionality.
214///
215/// This module provides the necessary types and functions to create and manage subscriptions
216/// to Lightstreamer items. It includes the `Subscription` struct, subscription modes,
217/// item updates, and subscription listeners.
218pub mod subscription;
219
220/// Module containing utility functions and error types.
221///
222/// This module provides common utilities and error types used throughout the library,
223/// including exception types for handling illegal arguments and states.
224pub mod utils;
225
226/// Module containing client-related functionality.
227///
228/// This module provides the main `LightstreamerClient` type and related components for
229/// connecting to Lightstreamer servers, managing sessions, and handling client events.
230pub mod client;
231
232/// Module containing connection-related functionality.
233///
234/// This module provides types for managing connection details and options.
235mod connection;