Skip to main content

nautilus_binance/spot/websocket/streams/
messages.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Binance Spot WebSocket message types.
17//!
18//! The handler emits venue-specific types via [`BinanceSpotWsMessage`].
19//! Data client layers convert these to Nautilus domain types.
20
21use nautilus_network::websocket::WebSocketClient;
22use serde::{Deserialize, Serialize};
23
24use crate::common::enums::BinanceWsMethod;
25pub use crate::spot::sbe::stream::{
26    BestBidAskStreamEvent, DepthDiffStreamEvent, DepthSnapshotStreamEvent, PriceLevel, Trade,
27    TradesStreamEvent,
28};
29
30/// Output message from the Spot WebSocket streams handler.
31///
32/// Contains venue-specific SBE-decoded event types. The data client layer
33/// converts these to Nautilus domain types using parse functions with
34/// instrument context.
35#[derive(Debug, Clone)]
36pub enum BinanceSpotWsMessage {
37    /// Trade stream events (SBE decoded).
38    Trades(TradesStreamEvent),
39    /// Best bid/ask stream event (SBE decoded).
40    BestBidAsk(BestBidAskStreamEvent),
41    /// Depth snapshot stream event (SBE decoded).
42    DepthSnapshot(DepthSnapshotStreamEvent),
43    /// Depth diff stream event (SBE decoded).
44    DepthDiff(DepthDiffStreamEvent),
45    /// Server shutdown notice (sent ~10 minutes before disconnection).
46    ServerShutdown(BinanceSpotServerShutdownMsg),
47    /// Raw binary message (unhandled SBE template).
48    RawBinary(Vec<u8>),
49    /// Raw JSON message (unhandled text frame).
50    RawJson(serde_json::Value),
51    /// Error from the server.
52    Error(BinanceWsErrorMsg),
53    /// WebSocket reconnected.
54    Reconnected,
55}
56
57/// Server shutdown event sent ~10 minutes before the venue disconnects clients.
58///
59/// # References
60///
61/// - <https://github.com/binance/binance-spot-api-docs/blob/master/CHANGELOG.md>
62#[derive(Debug, Clone, Deserialize)]
63pub struct BinanceSpotServerShutdownMsg {
64    /// Event type (`"serverShutdown"`).
65    #[serde(rename = "e")]
66    pub event_type: String,
67    /// Event time in milliseconds.
68    #[serde(rename = "E")]
69    pub event_time: i64,
70}
71
72/// Binance WebSocket error message.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct BinanceWsErrorMsg {
75    /// Error code from Binance.
76    pub code: i32,
77    /// Error message from Binance.
78    pub msg: String,
79}
80
81/// Commands sent from the outer client to the inner handler.
82///
83/// The handler runs in a dedicated Tokio task and processes these commands
84/// to perform WebSocket operations.
85#[allow(
86    missing_debug_implementations,
87    clippy::large_enum_variant,
88    reason = "Commands are ephemeral and immediately consumed"
89)]
90pub enum BinanceSpotWsStreamsCommand {
91    /// Set the WebSocket client after connection.
92    SetClient(WebSocketClient),
93    /// Disconnect and clean up.
94    Disconnect,
95    /// Subscribe to streams.
96    Subscribe { streams: Vec<String> },
97    /// Unsubscribe from streams.
98    Unsubscribe { streams: Vec<String> },
99}
100
101/// Binance WebSocket subscription request.
102#[derive(Debug, Clone, Serialize)]
103pub struct BinanceWsSubscription {
104    /// Request method.
105    pub method: BinanceWsMethod,
106    /// Stream names to subscribe/unsubscribe.
107    pub params: Vec<String>,
108    /// Request ID for correlation.
109    pub id: u64,
110}
111
112impl BinanceWsSubscription {
113    /// Create a subscribe request.
114    #[must_use]
115    pub fn subscribe(streams: Vec<String>, id: u64) -> Self {
116        Self {
117            method: BinanceWsMethod::Subscribe,
118            params: streams,
119            id,
120        }
121    }
122
123    /// Create an unsubscribe request.
124    #[must_use]
125    pub fn unsubscribe(streams: Vec<String>, id: u64) -> Self {
126        Self {
127            method: BinanceWsMethod::Unsubscribe,
128            params: streams,
129            id,
130        }
131    }
132}
133
134/// Binance WebSocket subscription response.
135#[derive(Debug, Clone, Deserialize)]
136pub struct BinanceWsResponse {
137    /// Result (null on success).
138    pub result: Option<serde_json::Value>,
139    /// Request ID for correlation.
140    pub id: u64,
141}
142
143/// Binance WebSocket error response.
144#[derive(Debug, Clone, Deserialize)]
145pub struct BinanceWsErrorResponse {
146    /// Error code.
147    pub code: i32,
148    /// Error message.
149    pub msg: String,
150    /// Request ID if available.
151    pub id: Option<u64>,
152}