|
@@ -11,7 +11,7 @@ use serde_json::json;
|
|
|
use serde_json::Value;
|
|
use serde_json::Value;
|
|
|
use tokio::sync::Mutex;
|
|
use tokio::sync::Mutex;
|
|
|
use tokio_tungstenite::tungstenite::{Message};
|
|
use tokio_tungstenite::tungstenite::{Message};
|
|
|
-use tracing::{error, info, trace};
|
|
|
|
|
|
|
+use tracing::{error, info, trace, warn};
|
|
|
use anyhow::Result;
|
|
use anyhow::Result;
|
|
|
|
|
|
|
|
use crate::exchange::response_base::Response;
|
|
use crate::exchange::response_base::Response;
|
|
@@ -215,12 +215,12 @@ impl MexcSpotWs {
|
|
|
let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
|
|
let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
|
|
|
|
|
|
|
|
loop {
|
|
loop {
|
|
|
- info!("Mexc_usdt_swap socket 连接中……");
|
|
|
|
|
|
|
+ trace!("Mexc_usdt_swap socket 连接中……");
|
|
|
AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
|
|
AbstractWsMode::ws_connect_async(is_shutdown_arc.clone(), handle_function.clone(), address_url.clone(),
|
|
|
false, tag.clone(), subscribe_array.clone(), write_to_socket_rx_arc.clone(),
|
|
false, tag.clone(), subscribe_array.clone(), write_to_socket_rx_arc.clone(),
|
|
|
Self::message_text, Self::message_ping, Self::message_pong, Self::message_binary).await;
|
|
Self::message_text, Self::message_ping, Self::message_pong, Self::message_binary).await;
|
|
|
|
|
|
|
|
- error!("Mexc_usdt_swap socket 断连,1s以后重连……");
|
|
|
|
|
|
|
+ warn!("Mexc_usdt_swap socket 断连,1s以后重连……");
|
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
@@ -233,8 +233,27 @@ impl MexcSpotWs {
|
|
|
|
|
|
|
|
//数据解析-Text
|
|
//数据解析-Text
|
|
|
pub fn message_text(text: String) -> Option<Response> {
|
|
pub fn message_text(text: String) -> Option<Response> {
|
|
|
- let response_data = Self::ok_text(text);
|
|
|
|
|
- Option::from(response_data)
|
|
|
|
|
|
|
+ let mut res_data = Response::new("".to_string(), -201, "success".to_string(), Value::Null);
|
|
|
|
|
+ let json_value: Value = serde_json::from_str(&text).unwrap();
|
|
|
|
|
+
|
|
|
|
|
+ match json_value["msg"].as_str() {
|
|
|
|
|
+ Some(msg) => {
|
|
|
|
|
+ res_data.message = json_value["msg"].to_string();
|
|
|
|
|
+
|
|
|
|
|
+ if msg.contains("Not Subscribed successfully!") {
|
|
|
|
|
+ res_data.code = 500
|
|
|
|
|
+ } else {
|
|
|
|
|
+ res_data.channel = json_value["msg"].to_string();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ None => {
|
|
|
|
|
+ res_data.data = json_value.clone();
|
|
|
|
|
+ res_data.code = -1;
|
|
|
|
|
+ res_data.message = text;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Option::from(res_data)
|
|
|
}
|
|
}
|
|
|
//数据解析-ping
|
|
//数据解析-ping
|
|
|
pub fn message_ping(_pi: Vec<u8>) -> Option<Response> {
|
|
pub fn message_ping(_pi: Vec<u8>) -> Option<Response> {
|
|
@@ -269,22 +288,22 @@ impl MexcSpotWs {
|
|
|
kline_message.topic_info.clone(), // 使用解析到的 Topic 信息
|
|
kline_message.topic_info.clone(), // 使用解析到的 Topic 信息
|
|
|
200,
|
|
200,
|
|
|
"success".to_string(),
|
|
"success".to_string(),
|
|
|
- json!({
|
|
|
|
|
- "interval": kline_data.interval,
|
|
|
|
|
- "windowStart": kline_data.window_start, //注意 snake_case
|
|
|
|
|
- "openingPrice": kline_data.opening_price,
|
|
|
|
|
- "closingPrice": kline_data.closing_price,
|
|
|
|
|
- "highestPrice": kline_data.highest_price,
|
|
|
|
|
- "lowestPrice": kline_data.lowest_price,
|
|
|
|
|
- "volume": kline_data.volume,
|
|
|
|
|
- "amount": kline_data.amount,
|
|
|
|
|
- "windowEnd": kline_data.window_end,
|
|
|
|
|
- // 可以添加顶层字段的信息,如果需要
|
|
|
|
|
- "topic_info": kline_message.topic_info,
|
|
|
|
|
- "symbol": kline_message.symbol,
|
|
|
|
|
- "id_info": kline_message.id_info,
|
|
|
|
|
- "timestamp_or_version": kline_message.timestamp_or_version,
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ json!({
|
|
|
|
|
+ "interval": kline_data.interval,
|
|
|
|
|
+ "windowStart": kline_data.window_start, //注意 snake_case
|
|
|
|
|
+ "openingPrice": kline_data.opening_price,
|
|
|
|
|
+ "closingPrice": kline_data.closing_price,
|
|
|
|
|
+ "highestPrice": kline_data.highest_price,
|
|
|
|
|
+ "lowestPrice": kline_data.lowest_price,
|
|
|
|
|
+ "volume": kline_data.volume,
|
|
|
|
|
+ "amount": kline_data.amount,
|
|
|
|
|
+ "windowEnd": kline_data.window_end,
|
|
|
|
|
+ // 可以添加顶层字段的信息,如果需要
|
|
|
|
|
+ "topic_info": kline_message.topic_info,
|
|
|
|
|
+ "symbol": kline_message.symbol,
|
|
|
|
|
+ "id_info": kline_message.id_info,
|
|
|
|
|
+ "timestamp_or_version": kline_message.timestamp_or_version,
|
|
|
|
|
+ })
|
|
|
);
|
|
);
|
|
|
return Some(response_data);
|
|
return Some(response_data);
|
|
|
} else {
|
|
} else {
|
|
@@ -342,7 +361,6 @@ impl MexcSpotWs {
|
|
|
})
|
|
})
|
|
|
);
|
|
);
|
|
|
return Some(response_data);
|
|
return Some(response_data);
|
|
|
-
|
|
|
|
|
} else {
|
|
} else {
|
|
|
info!("顶层深度消息结构解析成功,但未找到嵌套的 depth_data 字段 (Tag 313)");
|
|
info!("顶层深度消息结构解析成功,但未找到嵌套的 depth_data 字段 (Tag 313)");
|
|
|
// 处理只有顶层字段的深度相关消息
|
|
// 处理只有顶层字段的深度相关消息
|
|
@@ -378,61 +396,6 @@ impl MexcSpotWs {
|
|
|
}
|
|
}
|
|
|
Some(Response::new("".to_string(), 400, "无法解析未知二进制消息".to_string(), Value::Null))
|
|
Some(Response::new("".to_string(), 400, "无法解析未知二进制消息".to_string(), Value::Null))
|
|
|
}
|
|
}
|
|
|
- //数据解析
|
|
|
|
|
- pub fn ok_text(text: String) -> Response
|
|
|
|
|
- {
|
|
|
|
|
- info!("{}", text);
|
|
|
|
|
- let mut res_data = Response::new("".to_string(), 200, "success".to_string(), Value::Null);
|
|
|
|
|
- let json_value: Value = serde_json::from_str(&text).unwrap();
|
|
|
|
|
-
|
|
|
|
|
- match json_value["channel"].as_str() {
|
|
|
|
|
- Some(method) => {
|
|
|
|
|
- if method.contains("pong") {
|
|
|
|
|
- return Response::new("".to_string(), -301, "success".to_string(), Value::Null);
|
|
|
|
|
- } else if method.contains("rs.sub.") {
|
|
|
|
|
- //订阅响应
|
|
|
|
|
- let data = json_value["data"].as_str().unwrap();
|
|
|
|
|
- if method.contains(".depth") {
|
|
|
|
|
- res_data.channel = "futures.order_book".to_string();
|
|
|
|
|
- } else if method.contains(".kline") {
|
|
|
|
|
- res_data.channel = "futures.candlesticks".to_string();
|
|
|
|
|
- } else if method.contains(".deal") {
|
|
|
|
|
- res_data.channel = "futures.trades".to_string();
|
|
|
|
|
- } else {
|
|
|
|
|
- res_data.channel = "未知频道订阅".to_string();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if data == "success" {
|
|
|
|
|
- res_data.code = -201;
|
|
|
|
|
- res_data.message = "订阅成功".to_string();
|
|
|
|
|
- } else {
|
|
|
|
|
- res_data.code = 400;
|
|
|
|
|
- res_data.message = "订阅失败".to_string();
|
|
|
|
|
- }
|
|
|
|
|
- } else if method.contains("push.") {
|
|
|
|
|
- if method.contains(".depth") {
|
|
|
|
|
- res_data.channel = "futures.order_book".to_string();
|
|
|
|
|
- } else if method.contains(".kline") {
|
|
|
|
|
- res_data.channel = "futures.candlesticks".to_string();
|
|
|
|
|
- } else {
|
|
|
|
|
- res_data.channel = "未知频道推送".to_string();
|
|
|
|
|
- }
|
|
|
|
|
- res_data.code = 200;
|
|
|
|
|
- res_data.data = json_value.clone();
|
|
|
|
|
- } else {
|
|
|
|
|
- res_data.code = -1;
|
|
|
|
|
- res_data.message = "未知解析".to_string();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- None => {
|
|
|
|
|
- res_data.data = json_value.clone();
|
|
|
|
|
- res_data.code = -1;
|
|
|
|
|
- res_data.message = "未知解析".to_string();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- res_data
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
#[cfg(test)]
|