Explorar el Código

网络层代码结构整理完毕。

skyfffire hace 1 año
padre
commit
9a5ce0bad1

+ 255 - 255
exchanges/src/binance_spot_ws.rs

@@ -1,255 +1,255 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use serde_json::json;
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{info, trace};
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::AbstractWsMode;
-
-pub enum BinanceSpotWsType {
-    //订阅频道类型
-    PublicAndPrivate,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum BinanceSpotSubscribeType {
-    PuBookTicker,
-    PuAggTrade,
-    PuDepth20levels100ms,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BinanceSpotLogin {
-    pub api_key: String,
-    pub api_secret: String,
-}
-
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BinanceSpotWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号信息
-    login_param: Option<BinanceSpotLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<BinanceSpotSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl BinanceSpotWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<BinanceSpotLogin>, ws_type: BinanceSpotWsType) -> BinanceSpotWs {
-        return BinanceSpotWs::new_label("default-BinanceSpotWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<BinanceSpotLogin>, ws_type: BinanceSpotWsType) -> BinanceSpotWs {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            BinanceSpotWsType::PublicAndPrivate => {
-                "wss://stream.binance.com:9443/ws".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-        /*****返回结构体*******/
-        BinanceSpotWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 20,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<BinanceSpotSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 小写
-            *symbol = symbol.to_lowercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "");
-            *symbol = symbol.replace("-", "");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                BinanceSpotSubscribeType::PuBookTicker => false,
-                BinanceSpotSubscribeType::PuAggTrade => false,
-                BinanceSpotSubscribeType::PuDepth20levels100ms => false,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: BinanceSpotSubscribeType) -> String {
-        match subscribe_type {
-            BinanceSpotSubscribeType::PuAggTrade => {
-                format!("{}@aggTrade", symbol)
-            }
-            BinanceSpotSubscribeType::PuDepth20levels100ms => {
-                format!("{}@depth20@100ms", symbol)
-            }
-            BinanceSpotSubscribeType::PuBookTicker => {
-                format!("{}@bookTicker", symbol)
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut params = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                params.push(ty_str);
-            }
-        }
-
-        let str = json!({
-            "method": "SUBSCRIBE",
-            "params":  params,
-            "id": 1
-            });
-        str.to_string()
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        // let heartbeat_time = self.heartbeat_time.clone();
-
-
-        //心跳-- 方法内部线程启动
-        // let write_tx_clone1 = Arc::clone(write_tx_am);
-        // tokio::spawn(async move {
-        //     trace!("线程-异步心跳-开始");
-        //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Pong, heartbeat_time).await;
-        //     trace!("线程-异步心跳-结束");
-        // });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-        if login_is {
-            //登录相关
-        }
-        subscribe_array.push(subscription.to_string());
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array,
-                                                   write_rx, read_tx,
-                                                   Self::message_text,
-                                                   Self::message_ping,
-                                                   Self::message_pong,
-            ).await {
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:币安-现货链接关闭-{:?}",e); }
-            }
-            trace!("线程-异步链接-结束");
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "pong".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData {
-        // trace!("原始数据");
-        // trace!(?text);
-        let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-
-        if json_value.get("result").is_some() &&
-            json_value.get("id").is_some()
-        {
-            //订阅反馈
-            res_data.code = "-201".to_string();
-            res_data.channel = "".to_string();
-            res_data.message = "订阅成功!".to_string();
-        } else if json_value.get("e").is_some() &&
-            json_value["e"].as_str() == Option::from("aggTrade")
-        {
-            res_data.channel = "aggTrade".to_string();
-            res_data.data = text;
-        } else if json_value.get("u").is_some() &&
-            json_value.get("s").is_some() &&
-            json_value.get("b").is_some() &&
-            json_value.get("B").is_some() &&
-            json_value.get("a").is_some() &&
-            json_value.get("A").is_some()
-        {
-            res_data.channel = "bookTicker".to_string();
-            res_data.data = text;
-        } else if json_value.get("bids").is_some() &&
-            json_value.get("asks").is_some()
-        {
-            res_data.channel = "depth".to_string();
-            res_data.data = text;
-        } else {
-            res_data.code = "".to_string();
-            res_data.channel = "未知的频道".to_string();
-        }
-        res_data
-    }
-}
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+//
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use serde_json::json;
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{info, trace};
+//
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::AbstractWsMode;
+//
+// pub enum BinanceSpotWsType {
+//     //订阅频道类型
+//     PublicAndPrivate,
+// }
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum BinanceSpotSubscribeType {
+//     PuBookTicker,
+//     PuAggTrade,
+//     PuDepth20levels100ms,
+// }
+//
+// //账号信息
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct BinanceSpotLogin {
+//     pub api_key: String,
+//     pub api_secret: String,
+// }
+//
+//
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct BinanceSpotWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //账号信息
+//     login_param: Option<BinanceSpotLogin>,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<BinanceSpotSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl BinanceSpotWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub fn new(is_colo: bool, login_param: Option<BinanceSpotLogin>, ws_type: BinanceSpotWsType) -> BinanceSpotWs {
+//         return BinanceSpotWs::new_label("default-BinanceSpotWs".to_string(), is_colo, login_param, ws_type);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: Option<BinanceSpotLogin>, ws_type: BinanceSpotWsType) -> BinanceSpotWs {
+//         /*******公共频道-私有频道数据组装*/
+//         let address_url = match ws_type {
+//             BinanceSpotWsType::PublicAndPrivate => {
+//                 "wss://stream.binance.com:9443/ws".to_string()
+//             }
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",address_url);
+//         } else {
+//             info!("走普通通道:{}",address_url);
+//         }
+//         /*****返回结构体*******/
+//         BinanceSpotWs {
+//             label,
+//             address_url,
+//             login_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 20,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<BinanceSpotSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 小写
+//             *symbol = symbol.to_lowercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("_", "");
+//             *symbol = symbol.replace("-", "");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     //频道是否需要登录
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 BinanceSpotSubscribeType::PuBookTicker => false,
+//                 BinanceSpotSubscribeType::PuAggTrade => false,
+//                 BinanceSpotSubscribeType::PuDepth20levels100ms => false,
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: BinanceSpotSubscribeType) -> String {
+//         match subscribe_type {
+//             BinanceSpotSubscribeType::PuAggTrade => {
+//                 format!("{}@aggTrade", symbol)
+//             }
+//             BinanceSpotSubscribeType::PuDepth20levels100ms => {
+//                 format!("{}@depth20@100ms", symbol)
+//             }
+//             BinanceSpotSubscribeType::PuBookTicker => {
+//                 format!("{}@bookTicker", symbol)
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> String {
+//         let mut params = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
+//                 params.push(ty_str);
+//             }
+//         }
+//
+//         let str = json!({
+//             "method": "SUBSCRIBE",
+//             "params":  params,
+//             "id": 1
+//             });
+//         str.to_string()
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         // let heartbeat_time = self.heartbeat_time.clone();
+//
+//
+//         //心跳-- 方法内部线程启动
+//         // let write_tx_clone1 = Arc::clone(write_tx_am);
+//         // tokio::spawn(async move {
+//         //     trace!("线程-异步心跳-开始");
+//         //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Pong, heartbeat_time).await;
+//         //     trace!("线程-异步心跳-结束");
+//         // });
+//
+//         //设置订阅
+//         let mut subscribe_array = vec![];
+//         if login_is {
+//             //登录相关
+//         }
+//         subscribe_array.push(subscription.to_string());
+//
+//         //链接
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                                    label.clone(), subscribe_array,
+//                                                    write_rx, read_tx,
+//                                                    Self::message_text,
+//                                                    Self::message_ping,
+//                                                    Self::message_pong,
+//             ).await {
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:币安-现货链接关闭-{:?}",e); }
+//             }
+//             trace!("线程-异步链接-结束");
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "pong".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData {
+//         // trace!("原始数据");
+//         // trace!(?text);
+//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//
+//         if json_value.get("result").is_some() &&
+//             json_value.get("id").is_some()
+//         {
+//             //订阅反馈
+//             res_data.code = "-201".to_string();
+//             res_data.channel = "".to_string();
+//             res_data.message = "订阅成功!".to_string();
+//         } else if json_value.get("e").is_some() &&
+//             json_value["e"].as_str() == Option::from("aggTrade")
+//         {
+//             res_data.channel = "aggTrade".to_string();
+//             res_data.data = text;
+//         } else if json_value.get("u").is_some() &&
+//             json_value.get("s").is_some() &&
+//             json_value.get("b").is_some() &&
+//             json_value.get("B").is_some() &&
+//             json_value.get("a").is_some() &&
+//             json_value.get("A").is_some()
+//         {
+//             res_data.channel = "bookTicker".to_string();
+//             res_data.data = text;
+//         } else if json_value.get("bids").is_some() &&
+//             json_value.get("asks").is_some()
+//         {
+//             res_data.channel = "depth".to_string();
+//             res_data.data = text;
+//         } else {
+//             res_data.code = "".to_string();
+//             res_data.channel = "未知的频道".to_string();
+//         }
+//         res_data
+//     }
+// }

+ 7 - 6
exchanges/src/binance_swap_ws.rs

@@ -150,10 +150,9 @@ impl BinanceSwapWs {
     /*******************************************************************************************************/
     //链接
     pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
+                                  is_shutdown_arc: Arc<AtomicBool>,
                                   _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
+                                  write_rx: UnboundedReceiver<Message>) -> Result<(), Error>
     {
         let login_is = self.contains_pr();
         let subscription = self.get_subscription();
@@ -180,9 +179,11 @@ impl BinanceSwapWs {
         //链接
         let t2 = tokio::spawn(async move {
             trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array,
-                                                   write_rx, read_tx,
+            match AbstractWsMode::ws_connect_async(is_shutdown_arc,
+                                                   address_url.clone(),
+                                                   label.clone(),
+                                                   subscribe_array,
+                                                   write_rx,
                                                    Self::message_text,
                                                    Self::message_ping,
                                                    Self::message_pong,

+ 346 - 346
exchanges/src/bitget_spot_ws.rs

@@ -1,346 +1,346 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::Duration;
-
-use chrono::Utc;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use ring::hmac;
-use serde_json::{json, Value};
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{info, trace};
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum BitgetSpotWsType {
-    Public,
-    Private,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum BitgetSpotSubscribeType {
-    PuTicker,
-    PuCandle1m,
-    PuTrade,
-    PuBooks5,
-
-    PrAccount,
-    PrOrders,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BitgetSpotLogin {
-    pub api_key: String,
-    pub secret_key: String,
-    pub passphrase_key: String,
-}
-
-
-#[derive(Clone)]
-pub struct BitgetSpotWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号
-    login_param: Option<BitgetSpotLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<BitgetSpotSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl BitgetSpotWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<BitgetSpotLogin>, ws_type: BitgetSpotWsType) -> BitgetSpotWs {
-        return BitgetSpotWs::new_label("default-BitgetSpotWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<BitgetSpotLogin>, ws_type: BitgetSpotWsType) -> BitgetSpotWs
-    {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            BitgetSpotWsType::Public => {
-                format!("wss://ws.bitget.com/v2/ws/public")
-            }
-            BitgetSpotWsType::Private => {
-                format!("wss://ws.bitget.com/v2/ws/private")
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        BitgetSpotWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 10,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<BitgetSpotSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 小写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("-", "");
-            *symbol = symbol.replace("_", "");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                BitgetSpotSubscribeType::PuTicker => false,
-                BitgetSpotSubscribeType::PuCandle1m => false,
-                BitgetSpotSubscribeType::PuTrade => false,
-                BitgetSpotSubscribeType::PuBooks5 => false,
-
-                BitgetSpotSubscribeType::PrAccount => false,
-                BitgetSpotSubscribeType::PrOrders => false
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: BitgetSpotSubscribeType) -> Value {
-        match subscribe_type {
-            BitgetSpotSubscribeType::PuTicker => {
-                json!({
-                    "instType": "SPOT",
-                    "channel": "ticker",
-                    "instId": symbol,
-                })
-            }
-            BitgetSpotSubscribeType::PuCandle1m => {
-                json!({
-                    "instType": "SPOT",
-                    "channel": "candle1m",
-                    "instId": symbol,
-                })
-            }
-            BitgetSpotSubscribeType::PuTrade => {
-                json!({
-                    "instType": "SPOT",
-                    "channel": "trade",
-                    "instId": symbol,
-                })
-            }
-            BitgetSpotSubscribeType::PuBooks5 => {
-                json!({
-                    "instType": "SPOT",
-                    "channel": "books5",
-                    "instId": symbol,
-                })
-            }
-            BitgetSpotSubscribeType::PrAccount => {
-                json!({
-                    "instType": "SPOT",
-                    "channel": "account",
-                    "coin": "default"
-                })
-            }
-            BitgetSpotSubscribeType::PrOrders => {
-                json!({
-                    "instType": "SPOT",
-                    "channel": "orders",
-                    "instId": symbol
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut params = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                params.push(ty_str);
-            }
-        }
-        let str = json!({
-            "op": "subscribe",
-            "args": params
-        });
-
-        str.to_string()
-    }
-    //登录数据组装
-    fn log_in_to_str(&self) -> String {
-        let mut login_json_str = "".to_string();
-
-        let mut access_key: String = "".to_string();
-        let mut secret_key: String = "".to_string();
-        let mut passphrase: String = "".to_string();
-        match self.login_param.clone() {
-            None => {}
-            Some(param) => {
-                access_key = param.api_key;
-                secret_key = param.secret_key;
-                passphrase = param.passphrase_key;
-            }
-        }
-        if access_key.len() > 0 || secret_key.len() > 0 || passphrase.len() > 0 {
-            let timestamp = Utc::now().timestamp().to_string();
-            // 时间戳 + 请求类型+ 请求参数字符串
-            let message = format!("{}GET{}", timestamp, "/user/verify");
-            let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-            let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-            let sign = base64::encode(result);
-
-            let login_json = json!({
-                              "op": "login",
-                              "args": [{
-                                "apiKey": access_key,
-                                "passphrase": passphrase,
-                                "timestamp": timestamp,
-                                "sign": sign
-                              }]
-                        });
-
-            trace!("---login_json:{0}", login_json.to_string());
-            trace!("--登陆:{}", login_json.to_string());
-            login_json_str = login_json.to_string();
-        }
-        login_json_str
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.heartbeat_time.clone();
-
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-        if login_is {
-            //登录相关
-            let login_str = self.log_in_to_str();
-            let write_tx_clone2 = Arc::clone(write_tx_am);
-            AbstractWsMode::send_subscribe(write_tx_clone2, Message::Text(login_str)).await;
-            tokio::time::sleep(Duration::from_millis(1000 * 3)).await;
-        }
-        subscribe_array.push(subscription.to_string());
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array,
-                                                   write_rx, read_tx,
-                                                   Self::message_text,
-                                                   Self::message_ping,
-                                                   Self::message_pong,
-            ).await {
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:bitget-现货链接关闭-{:?}",e); }
-            }
-            trace!("线程-异步链接-结束");
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData
-    {
-        // trace!("原始数据:{}", text);
-        // trace!("大小:{}", text.capacity());
-        let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-
-        // {"event":"login","code":0}
-        if json_value.get("event").is_some() && json_value["event"].as_str() == Option::from("login") {
-            if json_value.get("code").is_some() && json_value["code"] == 0 {
-                res_data.message = format!("登陆成功");
-            } else {
-                res_data.message = format!("登陆失败:({},{})", json_value.get("code").as_ref().unwrap(), json_value.get("msg").as_ref().unwrap());
-            }
-            res_data.channel = format!("login");
-            res_data.code = "-200".to_string();
-            res_data
-        } else if json_value.get("event").is_some() && json_value["event"].as_str() == Option::from("subscribe") {
-            // trace!("解析-订阅反馈:{}", text);
-            res_data.code = "-201".to_string();
-            res_data.data = text;
-            res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-            res_data
-        } else if json_value.get("action").is_some() {
-            // trace!("解析-推送数据:{}", text);
-            res_data.data = json_value["data"].to_string();
-            if res_data.data == "[]" {
-                res_data.code = "".to_string();
-            } else {
-                res_data.code = "200".to_string();
-            }
-            res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-            res_data.reach_time = json_value["ts"].as_i64().unwrap() * 1000;
-            res_data
-        } else {
-            res_data
-        }
-    }
-}
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+// use std::time::Duration;
+//
+// use chrono::Utc;
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use ring::hmac;
+// use serde_json::{json, Value};
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{info, trace};
+//
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
+//
+// //类型
+// pub enum BitgetSpotWsType {
+//     Public,
+//     Private,
+// }
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum BitgetSpotSubscribeType {
+//     PuTicker,
+//     PuCandle1m,
+//     PuTrade,
+//     PuBooks5,
+//
+//     PrAccount,
+//     PrOrders,
+// }
+//
+// //账号信息
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct BitgetSpotLogin {
+//     pub api_key: String,
+//     pub secret_key: String,
+//     pub passphrase_key: String,
+// }
+//
+//
+// #[derive(Clone)]
+// pub struct BitgetSpotWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //账号
+//     login_param: Option<BitgetSpotLogin>,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<BitgetSpotSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl BitgetSpotWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub fn new(is_colo: bool, login_param: Option<BitgetSpotLogin>, ws_type: BitgetSpotWsType) -> BitgetSpotWs {
+//         return BitgetSpotWs::new_label("default-BitgetSpotWs".to_string(), is_colo, login_param, ws_type);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: Option<BitgetSpotLogin>, ws_type: BitgetSpotWsType) -> BitgetSpotWs
+//     {
+//         /*******公共频道-私有频道数据组装*/
+//         let address_url = match ws_type {
+//             BitgetSpotWsType::Public => {
+//                 format!("wss://ws.bitget.com/v2/ws/public")
+//             }
+//             BitgetSpotWsType::Private => {
+//                 format!("wss://ws.bitget.com/v2/ws/private")
+//             }
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",address_url);
+//         } else {
+//             info!("走普通通道:{}",address_url);
+//         }
+//
+//         BitgetSpotWs {
+//             label,
+//             address_url,
+//             login_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 10,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<BitgetSpotSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 小写
+//             *symbol = symbol.to_uppercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("-", "");
+//             *symbol = symbol.replace("_", "");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     //频道是否需要登录
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 BitgetSpotSubscribeType::PuTicker => false,
+//                 BitgetSpotSubscribeType::PuCandle1m => false,
+//                 BitgetSpotSubscribeType::PuTrade => false,
+//                 BitgetSpotSubscribeType::PuBooks5 => false,
+//
+//                 BitgetSpotSubscribeType::PrAccount => false,
+//                 BitgetSpotSubscribeType::PrOrders => false
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: BitgetSpotSubscribeType) -> Value {
+//         match subscribe_type {
+//             BitgetSpotSubscribeType::PuTicker => {
+//                 json!({
+//                     "instType": "SPOT",
+//                     "channel": "ticker",
+//                     "instId": symbol,
+//                 })
+//             }
+//             BitgetSpotSubscribeType::PuCandle1m => {
+//                 json!({
+//                     "instType": "SPOT",
+//                     "channel": "candle1m",
+//                     "instId": symbol,
+//                 })
+//             }
+//             BitgetSpotSubscribeType::PuTrade => {
+//                 json!({
+//                     "instType": "SPOT",
+//                     "channel": "trade",
+//                     "instId": symbol,
+//                 })
+//             }
+//             BitgetSpotSubscribeType::PuBooks5 => {
+//                 json!({
+//                     "instType": "SPOT",
+//                     "channel": "books5",
+//                     "instId": symbol,
+//                 })
+//             }
+//             BitgetSpotSubscribeType::PrAccount => {
+//                 json!({
+//                     "instType": "SPOT",
+//                     "channel": "account",
+//                     "coin": "default"
+//                 })
+//             }
+//             BitgetSpotSubscribeType::PrOrders => {
+//                 json!({
+//                     "instType": "SPOT",
+//                     "channel": "orders",
+//                     "instId": symbol
+//                 })
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> String {
+//         let mut params = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
+//                 params.push(ty_str);
+//             }
+//         }
+//         let str = json!({
+//             "op": "subscribe",
+//             "args": params
+//         });
+//
+//         str.to_string()
+//     }
+//     //登录数据组装
+//     fn log_in_to_str(&self) -> String {
+//         let mut login_json_str = "".to_string();
+//
+//         let mut access_key: String = "".to_string();
+//         let mut secret_key: String = "".to_string();
+//         let mut passphrase: String = "".to_string();
+//         match self.login_param.clone() {
+//             None => {}
+//             Some(param) => {
+//                 access_key = param.api_key;
+//                 secret_key = param.secret_key;
+//                 passphrase = param.passphrase_key;
+//             }
+//         }
+//         if access_key.len() > 0 || secret_key.len() > 0 || passphrase.len() > 0 {
+//             let timestamp = Utc::now().timestamp().to_string();
+//             // 时间戳 + 请求类型+ 请求参数字符串
+//             let message = format!("{}GET{}", timestamp, "/user/verify");
+//             let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
+//             let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
+//             let sign = base64::encode(result);
+//
+//             let login_json = json!({
+//                               "op": "login",
+//                               "args": [{
+//                                 "apiKey": access_key,
+//                                 "passphrase": passphrase,
+//                                 "timestamp": timestamp,
+//                                 "sign": sign
+//                               }]
+//                         });
+//
+//             trace!("---login_json:{0}", login_json.to_string());
+//             trace!("--登陆:{}", login_json.to_string());
+//             login_json_str = login_json.to_string();
+//         }
+//         login_json_str
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         let heartbeat_time = self.heartbeat_time.clone();
+//
+//
+//         //心跳-- 方法内部线程启动
+//         let write_tx_clone1 = Arc::clone(write_tx_am);
+//         tokio::spawn(async move {
+//             trace!("线程-异步心跳-开始");
+//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
+//             trace!("线程-异步心跳-结束");
+//         });
+//
+//         //设置订阅
+//         let mut subscribe_array = vec![];
+//         if login_is {
+//             //登录相关
+//             let login_str = self.log_in_to_str();
+//             let write_tx_clone2 = Arc::clone(write_tx_am);
+//             AbstractWsMode::send_subscribe(write_tx_clone2, Message::Text(login_str)).await;
+//             tokio::time::sleep(Duration::from_millis(1000 * 3)).await;
+//         }
+//         subscribe_array.push(subscription.to_string());
+//
+//         //链接
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                                    label.clone(), subscribe_array,
+//                                                    write_rx, read_tx,
+//                                                    Self::message_text,
+//                                                    Self::message_ping,
+//                                                    Self::message_pong,
+//             ).await {
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:bitget-现货链接关闭-{:?}",e); }
+//             }
+//             trace!("线程-异步链接-结束");
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData
+//     {
+//         // trace!("原始数据:{}", text);
+//         // trace!("大小:{}", text.capacity());
+//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//
+//         // {"event":"login","code":0}
+//         if json_value.get("event").is_some() && json_value["event"].as_str() == Option::from("login") {
+//             if json_value.get("code").is_some() && json_value["code"] == 0 {
+//                 res_data.message = format!("登陆成功");
+//             } else {
+//                 res_data.message = format!("登陆失败:({},{})", json_value.get("code").as_ref().unwrap(), json_value.get("msg").as_ref().unwrap());
+//             }
+//             res_data.channel = format!("login");
+//             res_data.code = "-200".to_string();
+//             res_data
+//         } else if json_value.get("event").is_some() && json_value["event"].as_str() == Option::from("subscribe") {
+//             // trace!("解析-订阅反馈:{}", text);
+//             res_data.code = "-201".to_string();
+//             res_data.data = text;
+//             res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
+//             res_data
+//         } else if json_value.get("action").is_some() {
+//             // trace!("解析-推送数据:{}", text);
+//             res_data.data = json_value["data"].to_string();
+//             if res_data.data == "[]" {
+//                 res_data.code = "".to_string();
+//             } else {
+//                 res_data.code = "200".to_string();
+//             }
+//             res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
+//             res_data.reach_time = json_value["ts"].as_i64().unwrap() * 1000;
+//             res_data
+//         } else {
+//             res_data
+//         }
+//     }
+// }

+ 339 - 339
exchanges/src/bybit_swap_ws.rs

@@ -1,339 +1,339 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-
-use chrono::Utc;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use serde_json::json;
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{info, trace};
-
-use ring::hmac;
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum BybitSwapWsType {
-    Public,
-    Private,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum BybitSwapSubscribeType {
-    PuOrderBook1,
-    PuOrderBook50,
-    PuBlicTrade,
-    PuTickers,
-    PuKline(String),
-
-    PrPosition,
-    PrExecution,
-    PrOrder,
-    PrWallet,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BybitSwapLogin {
-    pub api_key: String,
-    pub secret_key: String,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct BybitSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号
-    login_param: Option<BybitSwapLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<BybitSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl BybitSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<BybitSwapLogin>, ws_type: BybitSwapWsType) -> BybitSwapWs {
-        return BybitSwapWs::new_label("default-BybitSwapWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<BybitSwapLogin>, ws_type: BybitSwapWsType) -> BybitSwapWs {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            BybitSwapWsType::Public => {
-                "wss://stream.bybit.com/v5/public/linear?max_alive_time=1m".to_string()
-            }
-            BybitSwapWsType::Private => {
-                "wss://stream.bybit.com/v5/private?max_alive_time=1m".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        BybitSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 10,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<BybitSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "");
-            *symbol = symbol.replace("-", "");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                BybitSwapSubscribeType::PuOrderBook1 => false,
-                BybitSwapSubscribeType::PuOrderBook50 => false,
-                BybitSwapSubscribeType::PuBlicTrade => false,
-                BybitSwapSubscribeType::PuTickers => false,
-                BybitSwapSubscribeType::PuKline(_) => false,
-
-                BybitSwapSubscribeType::PrPosition => true,
-                BybitSwapSubscribeType::PrExecution => true,
-                BybitSwapSubscribeType::PrOrder => true,
-                BybitSwapSubscribeType::PrWallet => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: BybitSwapSubscribeType) -> String {
-        match subscribe_type {
-            BybitSwapSubscribeType::PuOrderBook1 => {
-                format!("orderbook.1.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuOrderBook50 => {
-                format!("orderbook.50.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuBlicTrade => {
-                format!("publicTrade.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuTickers => {
-                format!("tickers.{}", symbol)
-            }
-            BybitSwapSubscribeType::PuKline(t) => {
-                format!("kline.{}.{}", t, symbol)
-            }
-
-            BybitSwapSubscribeType::PrPosition => {
-                format!("position")
-            }
-            BybitSwapSubscribeType::PrExecution => {
-                format!("execution")
-            }
-            BybitSwapSubscribeType::PrOrder => {
-                format!("order")
-            }
-            BybitSwapSubscribeType::PrWallet => {
-                format!("wallet")
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut params = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                params.push(ty_str);
-            }
-        }
-
-        let str = json!({
-                "op": "subscribe",
-                "args": params
-            });
-        str.to_string()
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let timestamp = Utc::now().timestamp_millis();
-        let login_param = self.login_param.clone();
-        let (api_key, secret_key) = match login_param {
-            None => { ("".to_string(), "".to_string()) }
-            Some(p) => {
-                (p.api_key.clone().to_string(), p.secret_key.clone().to_string())
-            }
-        };
-        let heartbeat_time = self.heartbeat_time.clone();
-        trace!("{:?}",format!("{}",subscription));
-
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-        if login_is {
-            let expires = timestamp + 1000;
-            let message = format!("GET/realtime{}", expires);
-
-            let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-            let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-            let signature = hex::encode(result.as_ref());
-
-            //登录相关
-            let str = json!({
-                "op": "auth",
-                "args": [api_key, expires, signature]
-            });
-            subscribe_array.push(str.to_string());
-        }
-        subscribe_array.push(subscription.to_string());
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array,
-                                                   write_rx, read_tx,
-                                                   Self::message_text,
-                                                   Self::message_ping,
-                                                   Self::message_pong,
-            ).await {
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:bitget-期货链接关闭-{:?}",e); }
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData {
-        // trace!("原始数据");
-        // trace!(?text);
-        let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-        if json_value.get("success").is_some() {
-            //订阅内容
-            let success = json_value["success"].as_bool().unwrap();
-            // let ret_msg = json_value["ret_msg"].as_str().unwrap();
-            let op = json_value["op"].as_str().unwrap();
-            let success_error = if success {
-                "成功"
-            } else {
-                "失败"
-            };
-
-            if op == "auth" {
-                res_data.code = "-200".to_string();
-                res_data.message = format!("登录{}", success_error);
-            } else if op == "subscribe" {
-                res_data.message = format!("订阅{}", success_error);
-                res_data.code = "-201".to_string();
-            } else {
-                res_data.code = "".to_string();
-                res_data.channel = "未知订阅".to_string();
-            }
-        } else if json_value.get("topic").is_some() && json_value.get("data").is_some() {
-            let channel = json_value["topic"].to_string();
-            res_data.data = format!("{}", json_value.get("data").as_ref().unwrap());
-
-            res_data.code = "200".to_string();
-
-            if channel.contains("orderbook") {
-                res_data.channel = "orderbook".to_string();
-                res_data.data_type = json_value["type"].as_str().unwrap().to_string();
-                // bybit 时间在data块外
-                res_data.reach_time = json_value.get("ts").unwrap().as_i64().unwrap_or(0i64);
-            } else if channel.contains("publicTrade") {
-                res_data.channel = "trade".to_string();
-                res_data.data_type = json_value["type"].as_str().unwrap().to_string();
-            } else if channel.contains("tickers") {
-                res_data.channel = "tickers".to_string();
-            } else if channel.contains("kline") {
-                res_data.channel = "kline".to_string();
-            } else if channel.contains("position") {
-                res_data.channel = "position".to_string();
-            } else if channel.contains("execution") {
-                res_data.channel = "execution".to_string();
-            } else if channel.contains("order") {
-                res_data.channel = "order".to_string();
-            } else if channel.contains("wallet") {
-                res_data.channel = "wallet".to_string();
-            } else {
-                res_data.code = "".to_string();
-                res_data.channel = "未知的频道".to_string();
-            }
-        } else {
-            //推送数据
-            res_data.code = "".to_string();
-            res_data.channel = "未知的频道".to_string();
-        }
-
-        res_data
-    }
-}
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+//
+// use chrono::Utc;
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use serde_json::json;
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{info, trace};
+//
+// use ring::hmac;
+//
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
+//
+// //类型
+// pub enum BybitSwapWsType {
+//     Public,
+//     Private,
+// }
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum BybitSwapSubscribeType {
+//     PuOrderBook1,
+//     PuOrderBook50,
+//     PuBlicTrade,
+//     PuTickers,
+//     PuKline(String),
+//
+//     PrPosition,
+//     PrExecution,
+//     PrOrder,
+//     PrWallet,
+// }
+//
+// //账号信息
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct BybitSwapLogin {
+//     pub api_key: String,
+//     pub secret_key: String,
+// }
+//
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct BybitSwapWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //账号
+//     login_param: Option<BybitSwapLogin>,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<BybitSwapSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl BybitSwapWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub fn new(is_colo: bool, login_param: Option<BybitSwapLogin>, ws_type: BybitSwapWsType) -> BybitSwapWs {
+//         return BybitSwapWs::new_label("default-BybitSwapWs".to_string(), is_colo, login_param, ws_type);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: Option<BybitSwapLogin>, ws_type: BybitSwapWsType) -> BybitSwapWs {
+//         /*******公共频道-私有频道数据组装*/
+//         let address_url = match ws_type {
+//             BybitSwapWsType::Public => {
+//                 "wss://stream.bybit.com/v5/public/linear?max_alive_time=1m".to_string()
+//             }
+//             BybitSwapWsType::Private => {
+//                 "wss://stream.bybit.com/v5/private?max_alive_time=1m".to_string()
+//             }
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",address_url);
+//         } else {
+//             info!("走普通通道:{}",address_url);
+//         }
+//
+//         BybitSwapWs {
+//             label,
+//             address_url,
+//             login_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 10,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<BybitSwapSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 大写
+//             *symbol = symbol.to_uppercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("_", "");
+//             *symbol = symbol.replace("-", "");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     //频道是否需要登录
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 BybitSwapSubscribeType::PuOrderBook1 => false,
+//                 BybitSwapSubscribeType::PuOrderBook50 => false,
+//                 BybitSwapSubscribeType::PuBlicTrade => false,
+//                 BybitSwapSubscribeType::PuTickers => false,
+//                 BybitSwapSubscribeType::PuKline(_) => false,
+//
+//                 BybitSwapSubscribeType::PrPosition => true,
+//                 BybitSwapSubscribeType::PrExecution => true,
+//                 BybitSwapSubscribeType::PrOrder => true,
+//                 BybitSwapSubscribeType::PrWallet => true,
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: BybitSwapSubscribeType) -> String {
+//         match subscribe_type {
+//             BybitSwapSubscribeType::PuOrderBook1 => {
+//                 format!("orderbook.1.{}", symbol)
+//             }
+//             BybitSwapSubscribeType::PuOrderBook50 => {
+//                 format!("orderbook.50.{}", symbol)
+//             }
+//             BybitSwapSubscribeType::PuBlicTrade => {
+//                 format!("publicTrade.{}", symbol)
+//             }
+//             BybitSwapSubscribeType::PuTickers => {
+//                 format!("tickers.{}", symbol)
+//             }
+//             BybitSwapSubscribeType::PuKline(t) => {
+//                 format!("kline.{}.{}", t, symbol)
+//             }
+//
+//             BybitSwapSubscribeType::PrPosition => {
+//                 format!("position")
+//             }
+//             BybitSwapSubscribeType::PrExecution => {
+//                 format!("execution")
+//             }
+//             BybitSwapSubscribeType::PrOrder => {
+//                 format!("order")
+//             }
+//             BybitSwapSubscribeType::PrWallet => {
+//                 format!("wallet")
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> String {
+//         let mut params = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
+//                 params.push(ty_str);
+//             }
+//         }
+//
+//         let str = json!({
+//                 "op": "subscribe",
+//                 "args": params
+//             });
+//         str.to_string()
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         let timestamp = Utc::now().timestamp_millis();
+//         let login_param = self.login_param.clone();
+//         let (api_key, secret_key) = match login_param {
+//             None => { ("".to_string(), "".to_string()) }
+//             Some(p) => {
+//                 (p.api_key.clone().to_string(), p.secret_key.clone().to_string())
+//             }
+//         };
+//         let heartbeat_time = self.heartbeat_time.clone();
+//         trace!("{:?}",format!("{}",subscription));
+//
+//
+//         //心跳-- 方法内部线程启动
+//         let write_tx_clone1 = Arc::clone(write_tx_am);
+//         tokio::spawn(async move {
+//             trace!("线程-异步心跳-开始");
+//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
+//             trace!("线程-异步心跳-结束");
+//         });
+//
+//         //设置订阅
+//         let mut subscribe_array = vec![];
+//         if login_is {
+//             let expires = timestamp + 1000;
+//             let message = format!("GET/realtime{}", expires);
+//
+//             let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
+//             let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
+//             let signature = hex::encode(result.as_ref());
+//
+//             //登录相关
+//             let str = json!({
+//                 "op": "auth",
+//                 "args": [api_key, expires, signature]
+//             });
+//             subscribe_array.push(str.to_string());
+//         }
+//         subscribe_array.push(subscription.to_string());
+//
+//         //链接
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                                    label.clone(), subscribe_array,
+//                                                    write_rx, read_tx,
+//                                                    Self::message_text,
+//                                                    Self::message_ping,
+//                                                    Self::message_pong,
+//             ).await {
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:bitget-期货链接关闭-{:?}",e); }
+//             }
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData {
+//         // trace!("原始数据");
+//         // trace!(?text);
+//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//         if json_value.get("success").is_some() {
+//             //订阅内容
+//             let success = json_value["success"].as_bool().unwrap();
+//             // let ret_msg = json_value["ret_msg"].as_str().unwrap();
+//             let op = json_value["op"].as_str().unwrap();
+//             let success_error = if success {
+//                 "成功"
+//             } else {
+//                 "失败"
+//             };
+//
+//             if op == "auth" {
+//                 res_data.code = "-200".to_string();
+//                 res_data.message = format!("登录{}", success_error);
+//             } else if op == "subscribe" {
+//                 res_data.message = format!("订阅{}", success_error);
+//                 res_data.code = "-201".to_string();
+//             } else {
+//                 res_data.code = "".to_string();
+//                 res_data.channel = "未知订阅".to_string();
+//             }
+//         } else if json_value.get("topic").is_some() && json_value.get("data").is_some() {
+//             let channel = json_value["topic"].to_string();
+//             res_data.data = format!("{}", json_value.get("data").as_ref().unwrap());
+//
+//             res_data.code = "200".to_string();
+//
+//             if channel.contains("orderbook") {
+//                 res_data.channel = "orderbook".to_string();
+//                 res_data.data_type = json_value["type"].as_str().unwrap().to_string();
+//                 // bybit 时间在data块外
+//                 res_data.reach_time = json_value.get("ts").unwrap().as_i64().unwrap_or(0i64);
+//             } else if channel.contains("publicTrade") {
+//                 res_data.channel = "trade".to_string();
+//                 res_data.data_type = json_value["type"].as_str().unwrap().to_string();
+//             } else if channel.contains("tickers") {
+//                 res_data.channel = "tickers".to_string();
+//             } else if channel.contains("kline") {
+//                 res_data.channel = "kline".to_string();
+//             } else if channel.contains("position") {
+//                 res_data.channel = "position".to_string();
+//             } else if channel.contains("execution") {
+//                 res_data.channel = "execution".to_string();
+//             } else if channel.contains("order") {
+//                 res_data.channel = "order".to_string();
+//             } else if channel.contains("wallet") {
+//                 res_data.channel = "wallet".to_string();
+//             } else {
+//                 res_data.code = "".to_string();
+//                 res_data.channel = "未知的频道".to_string();
+//             }
+//         } else {
+//             //推送数据
+//             res_data.code = "".to_string();
+//             res_data.channel = "未知的频道".to_string();
+//         }
+//
+//         res_data
+//     }
+// }

+ 285 - 285
exchanges/src/crypto_spot_ws.rs

@@ -1,285 +1,285 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-
-use chrono::Utc;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use serde_json::json;
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{info, trace};
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::AbstractWsMode;
-
-//类型
-pub enum CryptoSpotWsType {
-    Public,
-    Private,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum CryptoSpotSubscribeType {
-    PuBook,
-    PuTicker,
-    PuTrade,
-    PuCandlestick,
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct CryptoSpotLogin {
-    pub api_key: String,
-    pub api_secret: String,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct CryptoSpotWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号
-    login_param: Option<CryptoSpotLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<CryptoSpotSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl CryptoSpotWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<CryptoSpotLogin>, ws_type: CryptoSpotWsType) -> CryptoSpotWs {
-        return CryptoSpotWs::new_label("default-CryptoSpotWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<CryptoSpotLogin>, ws_type: CryptoSpotWsType) -> CryptoSpotWs {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            CryptoSpotWsType::Public => {
-                "wss://stream.crypto.com/exchange/v1/market".to_string()
-            }
-            CryptoSpotWsType::Private => {
-                "wss://stream.crypto.com/exchange/v1/user".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        CryptoSpotWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 3,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<CryptoSpotSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "");
-            *symbol = symbol.replace("-", "");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                CryptoSpotSubscribeType::PuBook => false,
-                CryptoSpotSubscribeType::PuTicker => false,
-                CryptoSpotSubscribeType::PuTrade => false,
-                CryptoSpotSubscribeType::PuCandlestick => false,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: CryptoSpotSubscribeType) -> String {
-        match subscribe_type {
-            CryptoSpotSubscribeType::PuBook => {
-                format!("book.{}-PERP", symbol)
-            }
-            CryptoSpotSubscribeType::PuTicker => {
-                format!("ticker.{}-PERP", symbol)
-            }
-            CryptoSpotSubscribeType::PuTrade => {
-                format!("trade.{}-PERP", symbol)
-            }
-            CryptoSpotSubscribeType::PuCandlestick => {
-                format!("candlestick.M1.{}-PERP", symbol)
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut params = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                params.push(ty_str);
-            }
-        }
-
-        let nonce = Utc::now().timestamp_millis();
-        let str = json!({
-                  "id": 1,
-                  "method": "subscribe",
-                  "params": {
-                    "channels":params
-                  },
-                  "nonce": nonce
-                });
-
-        if params.len() > 0 {
-            str.to_string()
-        } else {
-            "".to_string()
-        }
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        // let heartbeat_time = self.heartbeat_time.clone();
-
-
-        //心跳-- 方法内部线程启动
-        // let write_tx_clone1 = Arc::clone(write_tx_am);
-        // tokio::spawn(async move {
-        //     trace!("线程-异步心跳-开始");
-        //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Pong, heartbeat_time).await;
-        //     trace!("线程-异步心跳-结束");
-        // });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-        if login_is {
-            //登录相关
-        }
-        subscribe_array.push(subscription.to_string());
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array,
-                                                   write_rx, read_tx,
-                                                   Self::message_text,
-                                                   Self::message_ping,
-                                                   Self::message_pong,
-            ).await {
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:crypt-期货链接关闭-{:?}",e); }
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData {
-        // trace!("原始数据");
-        // trace!(?text);
-
-        let mut res_data = ResponseData::new("".to_string(), "".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-
-        if json_value.get("id").is_some() && json_value.get("method").is_some() && json_value.get("code").is_some() {
-            let id = json_value["id"].as_i64().unwrap();
-            let method = json_value["method"].as_str().unwrap();
-            let code = json_value["code"].as_i64().unwrap();
-
-            if method == "public/heartbeat" {
-                if code == 0 {
-                    res_data.code = "-302".to_string();
-                    let str = json!({
-                  "id": id,
-                  "method": "public/respond-heartbeat"
-                });
-                    res_data.message = "服务器主动心跳检测,客户端回应~!".to_string();
-                    res_data.data = str.to_string();
-                } else {
-                    res_data.message = "心跳异常~!".to_string();
-                }
-            } else if method == "subscribe" && json_value.get("channel").is_some() {
-                //订阅反馈
-                if code == 0 {
-                    res_data.code = "-201".to_string();
-                    res_data.channel = json_value["channel"].as_str().unwrap().to_string();
-                } else {
-                    res_data.message = "订阅失败~!".to_string();
-                    res_data.data = json_value["data"].to_string()
-                }
-            } else if method == "subscribe" && json_value.get("result").is_some() {
-                if code == 0 {
-                    let subscription = json_value["result"]["subscription"].as_str().unwrap();
-                    res_data.channel = subscription.to_string();
-                    res_data.code = "200".to_string();
-                    res_data.data = json_value["result"]["data"].to_string()
-                } else {
-                    res_data.message = "推送数据异常~!".to_string();
-                    res_data.data = json_value["result"]["data"].to_string()
-                }
-            } else {
-                res_data.message = "未知解析!!".to_string();
-            }
-        } else {
-            res_data.message = "错误解析!!".to_string();
-        }
-        res_data
-    }
-}
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+//
+// use chrono::Utc;
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use serde_json::json;
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{info, trace};
+//
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::AbstractWsMode;
+//
+// //类型
+// pub enum CryptoSpotWsType {
+//     Public,
+//     Private,
+// }
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum CryptoSpotSubscribeType {
+//     PuBook,
+//     PuTicker,
+//     PuTrade,
+//     PuCandlestick,
+// }
+//
+// //账号信息
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct CryptoSpotLogin {
+//     pub api_key: String,
+//     pub api_secret: String,
+// }
+//
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct CryptoSpotWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //账号
+//     login_param: Option<CryptoSpotLogin>,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<CryptoSpotSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl CryptoSpotWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub fn new(is_colo: bool, login_param: Option<CryptoSpotLogin>, ws_type: CryptoSpotWsType) -> CryptoSpotWs {
+//         return CryptoSpotWs::new_label("default-CryptoSpotWs".to_string(), is_colo, login_param, ws_type);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: Option<CryptoSpotLogin>, ws_type: CryptoSpotWsType) -> CryptoSpotWs {
+//         /*******公共频道-私有频道数据组装*/
+//         let address_url = match ws_type {
+//             CryptoSpotWsType::Public => {
+//                 "wss://stream.crypto.com/exchange/v1/market".to_string()
+//             }
+//             CryptoSpotWsType::Private => {
+//                 "wss://stream.crypto.com/exchange/v1/user".to_string()
+//             }
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",address_url);
+//         } else {
+//             info!("走普通通道:{}",address_url);
+//         }
+//
+//         CryptoSpotWs {
+//             label,
+//             address_url,
+//             login_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 3,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<CryptoSpotSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 大写
+//             *symbol = symbol.to_uppercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("_", "");
+//             *symbol = symbol.replace("-", "");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     //频道是否需要登录
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 CryptoSpotSubscribeType::PuBook => false,
+//                 CryptoSpotSubscribeType::PuTicker => false,
+//                 CryptoSpotSubscribeType::PuTrade => false,
+//                 CryptoSpotSubscribeType::PuCandlestick => false,
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: CryptoSpotSubscribeType) -> String {
+//         match subscribe_type {
+//             CryptoSpotSubscribeType::PuBook => {
+//                 format!("book.{}-PERP", symbol)
+//             }
+//             CryptoSpotSubscribeType::PuTicker => {
+//                 format!("ticker.{}-PERP", symbol)
+//             }
+//             CryptoSpotSubscribeType::PuTrade => {
+//                 format!("trade.{}-PERP", symbol)
+//             }
+//             CryptoSpotSubscribeType::PuCandlestick => {
+//                 format!("candlestick.M1.{}-PERP", symbol)
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> String {
+//         let mut params = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
+//                 params.push(ty_str);
+//             }
+//         }
+//
+//         let nonce = Utc::now().timestamp_millis();
+//         let str = json!({
+//                   "id": 1,
+//                   "method": "subscribe",
+//                   "params": {
+//                     "channels":params
+//                   },
+//                   "nonce": nonce
+//                 });
+//
+//         if params.len() > 0 {
+//             str.to_string()
+//         } else {
+//             "".to_string()
+//         }
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   _write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         // let heartbeat_time = self.heartbeat_time.clone();
+//
+//
+//         //心跳-- 方法内部线程启动
+//         // let write_tx_clone1 = Arc::clone(write_tx_am);
+//         // tokio::spawn(async move {
+//         //     trace!("线程-异步心跳-开始");
+//         //     AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Pong, heartbeat_time).await;
+//         //     trace!("线程-异步心跳-结束");
+//         // });
+//
+//         //设置订阅
+//         let mut subscribe_array = vec![];
+//         if login_is {
+//             //登录相关
+//         }
+//         subscribe_array.push(subscription.to_string());
+//
+//         //链接
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                                    label.clone(), subscribe_array,
+//                                                    write_rx, read_tx,
+//                                                    Self::message_text,
+//                                                    Self::message_ping,
+//                                                    Self::message_pong,
+//             ).await {
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:crypt-期货链接关闭-{:?}",e); }
+//             }
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData {
+//         // trace!("原始数据");
+//         // trace!(?text);
+//
+//         let mut res_data = ResponseData::new("".to_string(), "".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//
+//         if json_value.get("id").is_some() && json_value.get("method").is_some() && json_value.get("code").is_some() {
+//             let id = json_value["id"].as_i64().unwrap();
+//             let method = json_value["method"].as_str().unwrap();
+//             let code = json_value["code"].as_i64().unwrap();
+//
+//             if method == "public/heartbeat" {
+//                 if code == 0 {
+//                     res_data.code = "-302".to_string();
+//                     let str = json!({
+//                   "id": id,
+//                   "method": "public/respond-heartbeat"
+//                 });
+//                     res_data.message = "服务器主动心跳检测,客户端回应~!".to_string();
+//                     res_data.data = str.to_string();
+//                 } else {
+//                     res_data.message = "心跳异常~!".to_string();
+//                 }
+//             } else if method == "subscribe" && json_value.get("channel").is_some() {
+//                 //订阅反馈
+//                 if code == 0 {
+//                     res_data.code = "-201".to_string();
+//                     res_data.channel = json_value["channel"].as_str().unwrap().to_string();
+//                 } else {
+//                     res_data.message = "订阅失败~!".to_string();
+//                     res_data.data = json_value["data"].to_string()
+//                 }
+//             } else if method == "subscribe" && json_value.get("result").is_some() {
+//                 if code == 0 {
+//                     let subscription = json_value["result"]["subscription"].as_str().unwrap();
+//                     res_data.channel = subscription.to_string();
+//                     res_data.code = "200".to_string();
+//                     res_data.data = json_value["result"]["data"].to_string()
+//                 } else {
+//                     res_data.message = "推送数据异常~!".to_string();
+//                     res_data.data = json_value["result"]["data"].to_string()
+//                 }
+//             } else {
+//                 res_data.message = "未知解析!!".to_string();
+//             }
+//         } else {
+//             res_data.message = "错误解析!!".to_string();
+//         }
+//         res_data
+//     }
+// }

+ 15 - 15
exchanges/src/gate_spot_ws.rs

@@ -1,15 +1,15 @@
-use std::collections::BTreeMap;
-
-#[derive(Clone)]
-pub struct GateSpotWs {}
-
-impl GateSpotWs {
-    pub fn new(_is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotWs
-    {
-        return GateSpotWs::new_label("default-GateSpotWs".to_string(), _is_colo, _login_param);
-    }
-    pub fn new_label(_label: String, _is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotWs
-    {
-        GateSpotWs {}
-    }
-}
+// use std::collections::BTreeMap;
+//
+// #[derive(Clone)]
+// pub struct GateSpotWs {}
+//
+// impl GateSpotWs {
+//     pub fn new(_is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotWs
+//     {
+//         return GateSpotWs::new_label("default-GateSpotWs".to_string(), _is_colo, _login_param);
+//     }
+//     pub fn new_label(_label: String, _is_colo: bool, _login_param: BTreeMap<String, String>) -> GateSpotWs
+//     {
+//         GateSpotWs {}
+//     }
+// }

+ 344 - 344
exchanges/src/gate_swap_ws.rs

@@ -1,344 +1,344 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use chrono::Utc;
-
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use hex;
-use hmac::{Hmac, Mac, NewMac};
-use serde_json::{json, Value};
-use sha2::Sha512;
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{info, trace};
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum GateSwapWsType {
-    PublicAndPrivate(String),
-}
-
-
-//订阅频道
-#[derive(Clone)]
-pub enum GateSwapSubscribeType {
-    PuFuturesOrderBook,
-    PuFuturesCandlesticks,
-    PuFuturesTrades,
-
-    PrFuturesOrders(String),
-    PrFuturesPositions(String),
-    PrFuturesBalances(String),
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct GateSwapLogin {
-    pub api_key: String,
-    pub secret: String,
-}
-
-
-#[derive(Clone)]
-pub struct GateSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号信息
-    login_param: Option<GateSwapLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<GateSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl GateSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<GateSwapLogin>, ws_type: GateSwapWsType) -> GateSwapWs {
-        return GateSwapWs::new_label("default-GateSwapWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<GateSwapLogin>, ws_type: GateSwapWsType) -> GateSwapWs
-    {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            GateSwapWsType::PublicAndPrivate(name) => {
-                if is_colo {
-                    let url = format!("wss://fxws-private.gateapi.io/v4/ws/{}", name.to_string());
-                    info!("开启高速通道:{:?}",url);
-                    url
-                } else {
-                    let url = format!("wss://fx-ws.gateio.ws/v4/ws/{}", name.to_string());
-                    info!("走普通通道:{}",url);
-                    url
-                }
-            }
-        };
-
-
-        GateSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 10,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<GateSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("-", "_");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                GateSwapSubscribeType::PuFuturesOrderBook => false,
-                GateSwapSubscribeType::PuFuturesCandlesticks => false,
-                GateSwapSubscribeType::PuFuturesTrades => false,
-
-                GateSwapSubscribeType::PrFuturesOrders(_) => true,
-                GateSwapSubscribeType::PrFuturesPositions(_) => true,
-                GateSwapSubscribeType::PrFuturesBalances(_) => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: GateSwapSubscribeType, login_param: Option<GateSwapLogin>) -> Value {
-        let time = chrono::Utc::now().timestamp();
-        let mut access_key = "".to_string();
-        let mut secret_key = "".to_string();
-        match login_param {
-            None => {}
-            Some(param) => {
-                access_key = param.api_key.clone();
-                secret_key = param.secret.clone();
-            }
-        }
-
-        match subscribe_type {
-            GateSwapSubscribeType::PuFuturesOrderBook => {
-                json!({
-                    "time": time,
-                    "channel": "futures.order_book",
-                    "event": "subscribe",
-                    "payload":  [symbol, "20", "0"]
-                })
-            }
-            GateSwapSubscribeType::PuFuturesCandlesticks => {
-                json!({
-                    "time": time,
-                    "channel": "futures.candlesticks",
-                    "event": "subscribe",
-                    "payload":  ["1m", symbol]
-                })
-            }
-            GateSwapSubscribeType::PrFuturesOrders(user_id) => {
-                json!({
-                    "time": time,
-                    "channel": "futures.orders",
-                    "event": "subscribe",
-                    "payload":  [user_id, symbol],
-                    "auth": {
-                        "method": "api_key",
-                        "KEY": access_key,
-                        "SIGN":Self::sign(secret_key.to_string(),
-                              "futures.orders".to_string(),
-                              "subscribe".to_string(),
-                              time.to_string())
-                    }
-                })
-            }
-            GateSwapSubscribeType::PrFuturesPositions(user_id) => {
-                json!({
-                    "time": time,
-                    "channel": "futures.positions",
-                    "event": "subscribe",
-                    "payload":  [user_id, symbol],
-                    "auth": {
-                        "method": "api_key",
-                        "KEY": access_key,
-                        "SIGN":Self::sign(secret_key.to_string(),
-                              "futures.positions".to_string(),
-                              "subscribe".to_string(),
-                              time.to_string())
-                    }
-                })
-            }
-            GateSwapSubscribeType::PrFuturesBalances(user_id) => {
-                json!({
-                    "time": time,
-                    "channel": "futures.balances",
-                    "event": "subscribe",
-                    "payload":  [user_id],
-                    "auth": {
-                        "method": "api_key",
-                        "KEY": access_key,
-                        "SIGN":Self::sign(secret_key.to_string(),
-                              "futures.balances".to_string(),
-                              "subscribe".to_string(),
-                              time.to_string())
-                    }
-                })
-            }
-            GateSwapSubscribeType::PuFuturesTrades => {
-                json!({
-                    "time": time,
-                    "channel": "futures.trades",
-                    "event": "subscribe",
-                    "payload":  [symbol]
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> Vec<Value> {
-        let mut args = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(),
-                                                  subscribe_type.clone(),
-                                                  self.login_param.clone(),
-                );
-                args.push(ty_str);
-            }
-        }
-        args
-    }
-    //生成签名
-    fn sign(secret_key: String, channel: String, event: String, time: String) -> String {
-        let message = format!("channel={}&event={}&time={}", channel, event, time);
-        let mut mac = Hmac::<Sha512>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
-        mac.update(message.as_bytes());
-        let result = mac.finalize().into_bytes();
-        let sign = hex::encode(result);
-        sign
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.heartbeat_time.clone();
-        let timestamp = Utc::now().timestamp();
-
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            let ping_str = json!({
-                "time" : timestamp,
-                "channel" : "futures.ping",
-            });
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Custom(ping_str.to_string()), heartbeat_time).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-        //设置订阅
-        let mut subscribe_array = vec![];
-        if login_is {
-            //登录相关
-        }
-        for s in subscription {
-            subscribe_array.push(s.to_string());
-        }
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array,
-                                                   write_rx, read_tx,
-                                                   Self::message_text,
-                                                   Self::message_ping,
-                                                   Self::message_pong,
-            ).await {
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:gate-期货链接关闭-{:?}",e); }
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData
-    {
-        // trace!("原始数据:{}", text);
-        let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-
-        if json_value["channel"].as_str() == Option::from("futures.pong") {
-            res_data.code = "-301".to_string();
-            res_data.message = "success".to_string();
-        } else if json_value.get("error").is_some() {
-            let message = json_value["error"]["message"].as_str().unwrap().to_string();
-            let mes = message.trim_end_matches('\n');
-
-            res_data.code = json_value["error"]["code"].to_string();
-            res_data.message = mes.to_string();
-        } else if json_value["result"]["status"].as_str() == Option::from("success") {//订阅返回
-            res_data.code = "-201".to_string();
-            res_data.data = text;
-        } else {
-            res_data.channel = format!("{}", json_value["channel"].as_str().unwrap());
-            res_data.code = "200".to_string();
-            res_data.data = json_value["result"].to_string();
-        }
-        res_data
-    }
-}
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+// use chrono::Utc;
+//
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use hex;
+// use hmac::{Hmac, Mac, NewMac};
+// use serde_json::{json, Value};
+// use sha2::Sha512;
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{info, trace};
+//
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
+//
+// //类型
+// pub enum GateSwapWsType {
+//     PublicAndPrivate(String),
+// }
+//
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum GateSwapSubscribeType {
+//     PuFuturesOrderBook,
+//     PuFuturesCandlesticks,
+//     PuFuturesTrades,
+//
+//     PrFuturesOrders(String),
+//     PrFuturesPositions(String),
+//     PrFuturesBalances(String),
+// }
+//
+// //账号信息
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct GateSwapLogin {
+//     pub api_key: String,
+//     pub secret: String,
+// }
+//
+//
+// #[derive(Clone)]
+// pub struct GateSwapWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //账号信息
+//     login_param: Option<GateSwapLogin>,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<GateSwapSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl GateSwapWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub fn new(is_colo: bool, login_param: Option<GateSwapLogin>, ws_type: GateSwapWsType) -> GateSwapWs {
+//         return GateSwapWs::new_label("default-GateSwapWs".to_string(), is_colo, login_param, ws_type);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: Option<GateSwapLogin>, ws_type: GateSwapWsType) -> GateSwapWs
+//     {
+//         /*******公共频道-私有频道数据组装*/
+//         let address_url = match ws_type {
+//             GateSwapWsType::PublicAndPrivate(name) => {
+//                 if is_colo {
+//                     let url = format!("wss://fxws-private.gateapi.io/v4/ws/{}", name.to_string());
+//                     info!("开启高速通道:{:?}",url);
+//                     url
+//                 } else {
+//                     let url = format!("wss://fx-ws.gateio.ws/v4/ws/{}", name.to_string());
+//                     info!("走普通通道:{}",url);
+//                     url
+//                 }
+//             }
+//         };
+//
+//
+//         GateSwapWs {
+//             label,
+//             address_url,
+//             login_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 10,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<GateSwapSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 大写
+//             *symbol = symbol.to_uppercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("-", "_");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     //频道是否需要登录
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 GateSwapSubscribeType::PuFuturesOrderBook => false,
+//                 GateSwapSubscribeType::PuFuturesCandlesticks => false,
+//                 GateSwapSubscribeType::PuFuturesTrades => false,
+//
+//                 GateSwapSubscribeType::PrFuturesOrders(_) => true,
+//                 GateSwapSubscribeType::PrFuturesPositions(_) => true,
+//                 GateSwapSubscribeType::PrFuturesBalances(_) => true,
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: GateSwapSubscribeType, login_param: Option<GateSwapLogin>) -> Value {
+//         let time = chrono::Utc::now().timestamp();
+//         let mut access_key = "".to_string();
+//         let mut secret_key = "".to_string();
+//         match login_param {
+//             None => {}
+//             Some(param) => {
+//                 access_key = param.api_key.clone();
+//                 secret_key = param.secret.clone();
+//             }
+//         }
+//
+//         match subscribe_type {
+//             GateSwapSubscribeType::PuFuturesOrderBook => {
+//                 json!({
+//                     "time": time,
+//                     "channel": "futures.order_book",
+//                     "event": "subscribe",
+//                     "payload":  [symbol, "20", "0"]
+//                 })
+//             }
+//             GateSwapSubscribeType::PuFuturesCandlesticks => {
+//                 json!({
+//                     "time": time,
+//                     "channel": "futures.candlesticks",
+//                     "event": "subscribe",
+//                     "payload":  ["1m", symbol]
+//                 })
+//             }
+//             GateSwapSubscribeType::PrFuturesOrders(user_id) => {
+//                 json!({
+//                     "time": time,
+//                     "channel": "futures.orders",
+//                     "event": "subscribe",
+//                     "payload":  [user_id, symbol],
+//                     "auth": {
+//                         "method": "api_key",
+//                         "KEY": access_key,
+//                         "SIGN":Self::sign(secret_key.to_string(),
+//                               "futures.orders".to_string(),
+//                               "subscribe".to_string(),
+//                               time.to_string())
+//                     }
+//                 })
+//             }
+//             GateSwapSubscribeType::PrFuturesPositions(user_id) => {
+//                 json!({
+//                     "time": time,
+//                     "channel": "futures.positions",
+//                     "event": "subscribe",
+//                     "payload":  [user_id, symbol],
+//                     "auth": {
+//                         "method": "api_key",
+//                         "KEY": access_key,
+//                         "SIGN":Self::sign(secret_key.to_string(),
+//                               "futures.positions".to_string(),
+//                               "subscribe".to_string(),
+//                               time.to_string())
+//                     }
+//                 })
+//             }
+//             GateSwapSubscribeType::PrFuturesBalances(user_id) => {
+//                 json!({
+//                     "time": time,
+//                     "channel": "futures.balances",
+//                     "event": "subscribe",
+//                     "payload":  [user_id],
+//                     "auth": {
+//                         "method": "api_key",
+//                         "KEY": access_key,
+//                         "SIGN":Self::sign(secret_key.to_string(),
+//                               "futures.balances".to_string(),
+//                               "subscribe".to_string(),
+//                               time.to_string())
+//                     }
+//                 })
+//             }
+//             GateSwapSubscribeType::PuFuturesTrades => {
+//                 json!({
+//                     "time": time,
+//                     "channel": "futures.trades",
+//                     "event": "subscribe",
+//                     "payload":  [symbol]
+//                 })
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> Vec<Value> {
+//         let mut args = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(),
+//                                                   subscribe_type.clone(),
+//                                                   self.login_param.clone(),
+//                 );
+//                 args.push(ty_str);
+//             }
+//         }
+//         args
+//     }
+//     //生成签名
+//     fn sign(secret_key: String, channel: String, event: String, time: String) -> String {
+//         let message = format!("channel={}&event={}&time={}", channel, event, time);
+//         let mut mac = Hmac::<Sha512>::new_varkey(secret_key.as_bytes()).expect("Failed to create HMAC");
+//         mac.update(message.as_bytes());
+//         let result = mac.finalize().into_bytes();
+//         let sign = hex::encode(result);
+//         sign
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         let heartbeat_time = self.heartbeat_time.clone();
+//         let timestamp = Utc::now().timestamp();
+//
+//
+//         //心跳-- 方法内部线程启动
+//         let write_tx_clone1 = Arc::clone(write_tx_am);
+//         tokio::spawn(async move {
+//             trace!("线程-异步心跳-开始");
+//             let ping_str = json!({
+//                 "time" : timestamp,
+//                 "channel" : "futures.ping",
+//             });
+//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Custom(ping_str.to_string()), heartbeat_time).await;
+//             trace!("线程-异步心跳-结束");
+//         });
+//
+//         //设置订阅
+//         let mut subscribe_array = vec![];
+//         if login_is {
+//             //登录相关
+//         }
+//         for s in subscription {
+//             subscribe_array.push(s.to_string());
+//         }
+//
+//         //链接
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                                    label.clone(), subscribe_array,
+//                                                    write_rx, read_tx,
+//                                                    Self::message_text,
+//                                                    Self::message_ping,
+//                                                    Self::message_pong,
+//             ).await {
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:gate-期货链接关闭-{:?}",e); }
+//             }
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData
+//     {
+//         // trace!("原始数据:{}", text);
+//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//
+//         if json_value["channel"].as_str() == Option::from("futures.pong") {
+//             res_data.code = "-301".to_string();
+//             res_data.message = "success".to_string();
+//         } else if json_value.get("error").is_some() {
+//             let message = json_value["error"]["message"].as_str().unwrap().to_string();
+//             let mes = message.trim_end_matches('\n');
+//
+//             res_data.code = json_value["error"]["code"].to_string();
+//             res_data.message = mes.to_string();
+//         } else if json_value["result"]["status"].as_str() == Option::from("success") {//订阅返回
+//             res_data.code = "-201".to_string();
+//             res_data.data = text;
+//         } else {
+//             res_data.channel = format!("{}", json_value["channel"].as_str().unwrap());
+//             res_data.code = "200".to_string();
+//             res_data.data = json_value["result"].to_string();
+//         }
+//         res_data
+//     }
+// }

+ 378 - 378
exchanges/src/kucoin_spot_ws.rs

@@ -1,378 +1,378 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{error, info, trace};
-
-use crate::kucoin_spot_rest::KucoinSpotRest;
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum KucoinSpotWsType {
-    Public,
-    Private,
-}
-
-#[derive(Debug)]
-#[derive(Clone)]
-pub struct KucoinSpotWsParam {
-    pub token: String,
-    pub ws_url: String,
-    pub ws_ping_interval: i64,
-    pub ws_ping_timeout: i64,
-    pub is_ok_subscribe: bool,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum KucoinSpotSubscribeType {
-    PuSpotMarketLevel2Depth50,
-    PuMarketMatch,
-    PuMarketTicker,
-
-    PrSpotMarketTradeOrders,
-    PrAccountBalance,
-}
-
-//账号信息
-#[derive(Clone, Debug)]
-pub struct KucoinSpotLogin {
-    pub access_key: String,
-    pub secret_key: String,
-    pub pass_key: String,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct KucoinSpotWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //代理信息
-    login_param: Option<KucoinSpotLogin>,
-    //登陆数据
-    ws_param: KucoinSpotWsParam,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<KucoinSpotSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl KucoinSpotWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub async fn new(is_colo: bool, login_param: Option<KucoinSpotLogin>, ws_type: KucoinSpotWsType) -> KucoinSpotWs {
-        return KucoinSpotWs::new_label("default-KucoinSpotWs".to_string(), is_colo, login_param, ws_type).await;
-    }
-    pub async fn new_label(label: String, is_colo: bool, login_param: Option<KucoinSpotLogin>, ws_type: KucoinSpotWsType) -> KucoinSpotWs {
-        /*******公共频道-私有频道数据组装*/
-        let mut ws_param = KucoinSpotWsParam {
-            token: "".to_string(),
-            ws_url: "".to_string(),
-            ws_ping_interval: 0,
-            ws_ping_timeout: 0,
-            is_ok_subscribe: false,
-        };
-
-        /*******公共频道-私有频道数据组装*/
-        let res_data = KucoinSpotWs::get_rul_token(ws_type, login_param.clone()).await;
-        let address_url = match res_data {
-            Ok(param) => {
-                ws_param = param;
-                format!("{}?token={}", ws_param.ws_url, ws_param.token)
-            }
-            Err(error) => {
-                error!("-链接地址等参数错误:{:?}", error);
-                "".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        KucoinSpotWs {
-            label,
-            address_url,
-            login_param,
-            ws_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 18,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //根据当前类型获取对应的频道 地址 与 token
-    async fn get_rul_token(ws_type: KucoinSpotWsType, login_param: Option<KucoinSpotLogin>) -> Result<KucoinSpotWsParam, reqwest::Error> {
-        let mut kucoin_exc = KucoinSpotRest::new(false, match login_param {
-            None => {
-                let btree_map: BTreeMap<String, String> = BTreeMap::new();
-                btree_map
-            }
-            Some(d) => {
-                let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-                btree_map.insert("access_key".to_string(), d.access_key);
-                btree_map.insert("secret_key".to_string(), d.secret_key);
-                btree_map.insert("pass_key".to_string(), d.pass_key);
-                btree_map
-            }
-        });
-        let res_data = match ws_type {
-            KucoinSpotWsType::Public => {
-                kucoin_exc.get_public_token().await
-            }
-            KucoinSpotWsType::Private => {
-                kucoin_exc.get_private_token().await
-            }
-        };
-
-        trace!("kucoin-spot-rest 获取ws连接地址:{:?}",res_data);
-
-        if res_data.code == "200" {
-            let mut ws_url = "".to_string();
-            let mut ws_token = "".to_string();
-            let mut ws_ping_interval: i64 = 0;
-            let mut ws_ping_timeout: i64 = 0;
-
-
-            //数据解析
-            let parsed_json: serde_json::Value = serde_json::from_str(res_data.data.as_str()).unwrap();
-            if let Some(value) = parsed_json.get("token") {
-                let formatted_value = match value {
-                    serde_json::Value::String(s) => s.clone(),
-                    _ => value.to_string()
-                };
-                ws_token = format!("{}", formatted_value);
-            }
-            if let Some(endpoint) = parsed_json["instanceServers"][0]["endpoint"].as_str() {
-                ws_url = format!("{}", endpoint);
-            }
-            if let Some(ping_interval) = parsed_json["instanceServers"][0]["pingInterval"].as_i64() {
-                ws_ping_interval = ping_interval;
-            }
-            if let Some(ping_timeout) = parsed_json["instanceServers"][0]["pingTimeout"].as_i64() {
-                ws_ping_timeout = ping_timeout;
-            }
-
-
-            Ok(KucoinSpotWsParam { ws_url, token: ws_token, ws_ping_interval, ws_ping_timeout, is_ok_subscribe: false })
-        } else {
-            error!("公共/私有-频道获取失败:{:?}", res_data);
-            panic!("公共/私有-频道获取失败:{:?}", res_data);
-        }
-    }
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<KucoinSpotSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "-");
-        }
-        self.symbol_s = b_array;
-    }
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50 => false,
-                KucoinSpotSubscribeType::PuMarketMatch => false,
-                KucoinSpotSubscribeType::PuMarketTicker => false,
-
-                KucoinSpotSubscribeType::PrSpotMarketTradeOrders => true,
-                KucoinSpotSubscribeType::PrAccountBalance => true
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: KucoinSpotSubscribeType) -> serde_json::Value {
-        match subscribe_type {
-            KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50 => {//level2
-                serde_json::json!({
-                     "topic": format!("/spotMarket/level2Depth50:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSpotSubscribeType::PuMarketMatch => {//match
-                serde_json::json!({
-                     "topic": format!("/market/match:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSpotSubscribeType::PuMarketTicker => {//ticker
-                serde_json::json!({
-                     "topic": format!("/market/ticker:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-
-            KucoinSpotSubscribeType::PrSpotMarketTradeOrders => {//market.tradeOrders
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": "/spotMarket/tradeOrders",
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-            KucoinSpotSubscribeType::PrAccountBalance => {//account.balance
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": "/account/balance",
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> Vec<String> {
-        let mut array = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                array.push(ty_str.to_string());
-            }
-        }
-        array
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>,
-    ) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.ws_param.ws_ping_interval;
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = write_tx_am.clone();
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time as u64).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-
-        //设置订阅
-        let subscribe_array = subscription.clone();
-        if login_is {
-            //登录相关
-        }
-        // let write_tx_clone2 = write_tx_am.clone();
-        // tokio::spawn(async move {
-        //     tokio::time::sleep(Duration::from_millis(3 * 1000)).await;
-        //     for su in subscription.clone(){
-        //         let write_tx_clone = write_tx_clone2.lock().await;
-        //         let message = Message::Text(su.clone());
-        //         write_tx_clone.unbounded_send(message).unwrap();
-        //     }
-        // });
-
-
-        //1 链接
-
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array.clone(),
-                                                   write_rx, read_tx,
-                                                   Self::message_text,
-                                                   Self::message_ping,
-                                                   Self::message_pong,
-            ).await {
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:kucoin-现货链接关闭-{:?}",e); }
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData
-    {
-        let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-        //订阅 相应
-        if json_value["type"].as_str() == Option::from("welcome") {
-            //链接成功
-            res_data.code = "-200".to_string();
-            res_data.message = "链接成功,主动发起订阅".to_string();
-            trace!("链接成功,主动发起订阅:");
-        } else if json_value["type"].as_str() == Option::from("ack") {
-            res_data.code = "-201".to_string();
-            res_data.message = "订阅成功".to_string();
-        } else if json_value["type"].as_str() == Option::from("error") {
-            res_data.code = format!("{}", json_value["code"]);
-            res_data.message = format!("{}", json_value["data"].as_str().unwrap());
-        } else if json_value.get("topic").is_some() {
-            res_data.channel = format!("{}", json_value["subject"].as_str().unwrap());
-
-            if json_value["topic"].as_str() == Option::from("/contractAccount/wallet") {
-                res_data.code = "".to_string();
-                if json_value["subject"].as_str() == Option::from("availableBalance.change") {
-                    res_data.code = "200".to_string();
-                    res_data.data = json_value["data"].to_string();
-                } else {}
-            } else {
-                res_data.data = json_value["data"].to_string();
-            }
-        } else {
-            res_data.code = "".to_string();
-            res_data.message = "未知解析".to_string();
-        }
-        res_data
-    }
-}
+// use std::collections::BTreeMap;
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+//
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{error, info, trace};
+//
+// use crate::kucoin_spot_rest::KucoinSpotRest;
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
+//
+// //类型
+// pub enum KucoinSpotWsType {
+//     Public,
+//     Private,
+// }
+//
+// #[derive(Debug)]
+// #[derive(Clone)]
+// pub struct KucoinSpotWsParam {
+//     pub token: String,
+//     pub ws_url: String,
+//     pub ws_ping_interval: i64,
+//     pub ws_ping_timeout: i64,
+//     pub is_ok_subscribe: bool,
+// }
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum KucoinSpotSubscribeType {
+//     PuSpotMarketLevel2Depth50,
+//     PuMarketMatch,
+//     PuMarketTicker,
+//
+//     PrSpotMarketTradeOrders,
+//     PrAccountBalance,
+// }
+//
+// //账号信息
+// #[derive(Clone, Debug)]
+// pub struct KucoinSpotLogin {
+//     pub access_key: String,
+//     pub secret_key: String,
+//     pub pass_key: String,
+// }
+//
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct KucoinSpotWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //代理信息
+//     login_param: Option<KucoinSpotLogin>,
+//     //登陆数据
+//     ws_param: KucoinSpotWsParam,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<KucoinSpotSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl KucoinSpotWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub async fn new(is_colo: bool, login_param: Option<KucoinSpotLogin>, ws_type: KucoinSpotWsType) -> KucoinSpotWs {
+//         return KucoinSpotWs::new_label("default-KucoinSpotWs".to_string(), is_colo, login_param, ws_type).await;
+//     }
+//     pub async fn new_label(label: String, is_colo: bool, login_param: Option<KucoinSpotLogin>, ws_type: KucoinSpotWsType) -> KucoinSpotWs {
+//         /*******公共频道-私有频道数据组装*/
+//         let mut ws_param = KucoinSpotWsParam {
+//             token: "".to_string(),
+//             ws_url: "".to_string(),
+//             ws_ping_interval: 0,
+//             ws_ping_timeout: 0,
+//             is_ok_subscribe: false,
+//         };
+//
+//         /*******公共频道-私有频道数据组装*/
+//         let res_data = KucoinSpotWs::get_rul_token(ws_type, login_param.clone()).await;
+//         let address_url = match res_data {
+//             Ok(param) => {
+//                 ws_param = param;
+//                 format!("{}?token={}", ws_param.ws_url, ws_param.token)
+//             }
+//             Err(error) => {
+//                 error!("-链接地址等参数错误:{:?}", error);
+//                 "".to_string()
+//             }
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",address_url);
+//         } else {
+//             info!("走普通通道:{}",address_url);
+//         }
+//
+//         KucoinSpotWs {
+//             label,
+//             address_url,
+//             login_param,
+//             ws_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 18,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //根据当前类型获取对应的频道 地址 与 token
+//     async fn get_rul_token(ws_type: KucoinSpotWsType, login_param: Option<KucoinSpotLogin>) -> Result<KucoinSpotWsParam, reqwest::Error> {
+//         let mut kucoin_exc = KucoinSpotRest::new(false, match login_param {
+//             None => {
+//                 let btree_map: BTreeMap<String, String> = BTreeMap::new();
+//                 btree_map
+//             }
+//             Some(d) => {
+//                 let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
+//                 btree_map.insert("access_key".to_string(), d.access_key);
+//                 btree_map.insert("secret_key".to_string(), d.secret_key);
+//                 btree_map.insert("pass_key".to_string(), d.pass_key);
+//                 btree_map
+//             }
+//         });
+//         let res_data = match ws_type {
+//             KucoinSpotWsType::Public => {
+//                 kucoin_exc.get_public_token().await
+//             }
+//             KucoinSpotWsType::Private => {
+//                 kucoin_exc.get_private_token().await
+//             }
+//         };
+//
+//         trace!("kucoin-spot-rest 获取ws连接地址:{:?}",res_data);
+//
+//         if res_data.code == "200" {
+//             let mut ws_url = "".to_string();
+//             let mut ws_token = "".to_string();
+//             let mut ws_ping_interval: i64 = 0;
+//             let mut ws_ping_timeout: i64 = 0;
+//
+//
+//             //数据解析
+//             let parsed_json: serde_json::Value = serde_json::from_str(res_data.data.as_str()).unwrap();
+//             if let Some(value) = parsed_json.get("token") {
+//                 let formatted_value = match value {
+//                     serde_json::Value::String(s) => s.clone(),
+//                     _ => value.to_string()
+//                 };
+//                 ws_token = format!("{}", formatted_value);
+//             }
+//             if let Some(endpoint) = parsed_json["instanceServers"][0]["endpoint"].as_str() {
+//                 ws_url = format!("{}", endpoint);
+//             }
+//             if let Some(ping_interval) = parsed_json["instanceServers"][0]["pingInterval"].as_i64() {
+//                 ws_ping_interval = ping_interval;
+//             }
+//             if let Some(ping_timeout) = parsed_json["instanceServers"][0]["pingTimeout"].as_i64() {
+//                 ws_ping_timeout = ping_timeout;
+//             }
+//
+//
+//             Ok(KucoinSpotWsParam { ws_url, token: ws_token, ws_ping_interval, ws_ping_timeout, is_ok_subscribe: false })
+//         } else {
+//             error!("公共/私有-频道获取失败:{:?}", res_data);
+//             panic!("公共/私有-频道获取失败:{:?}", res_data);
+//         }
+//     }
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<KucoinSpotSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 大写
+//             *symbol = symbol.to_uppercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("_", "-");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50 => false,
+//                 KucoinSpotSubscribeType::PuMarketMatch => false,
+//                 KucoinSpotSubscribeType::PuMarketTicker => false,
+//
+//                 KucoinSpotSubscribeType::PrSpotMarketTradeOrders => true,
+//                 KucoinSpotSubscribeType::PrAccountBalance => true
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: KucoinSpotSubscribeType) -> serde_json::Value {
+//         match subscribe_type {
+//             KucoinSpotSubscribeType::PuSpotMarketLevel2Depth50 => {//level2
+//                 serde_json::json!({
+//                      "topic": format!("/spotMarket/level2Depth50:{}", symbol),
+//                      "type": "subscribe",
+//                      "response": true
+//                 })
+//             }
+//             KucoinSpotSubscribeType::PuMarketMatch => {//match
+//                 serde_json::json!({
+//                      "topic": format!("/market/match:{}", symbol),
+//                      "type": "subscribe",
+//                      "response": true
+//                 })
+//             }
+//             KucoinSpotSubscribeType::PuMarketTicker => {//ticker
+//                 serde_json::json!({
+//                      "topic": format!("/market/ticker:{}", symbol),
+//                      "type": "subscribe",
+//                      "response": true
+//                 })
+//             }
+//
+//             KucoinSpotSubscribeType::PrSpotMarketTradeOrders => {//market.tradeOrders
+//                 serde_json::json!({
+//                     "type": "subscribe",
+//                     "topic": "/spotMarket/tradeOrders",
+//                     "privateChannel":true,
+//                     "response":true,
+//                 })
+//             }
+//             KucoinSpotSubscribeType::PrAccountBalance => {//account.balance
+//                 serde_json::json!({
+//                     "type": "subscribe",
+//                     "topic": "/account/balance",
+//                     "privateChannel":true,
+//                     "response":true,
+//                 })
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> Vec<String> {
+//         let mut array = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
+//                 array.push(ty_str.to_string());
+//             }
+//         }
+//         array
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>,
+//     ) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         let heartbeat_time = self.ws_param.ws_ping_interval;
+//
+//         //心跳-- 方法内部线程启动
+//         let write_tx_clone1 = write_tx_am.clone();
+//         tokio::spawn(async move {
+//             trace!("线程-异步心跳-开始");
+//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time as u64).await;
+//             trace!("线程-异步心跳-结束");
+//         });
+//
+//
+//         //设置订阅
+//         let subscribe_array = subscription.clone();
+//         if login_is {
+//             //登录相关
+//         }
+//         // let write_tx_clone2 = write_tx_am.clone();
+//         // tokio::spawn(async move {
+//         //     tokio::time::sleep(Duration::from_millis(3 * 1000)).await;
+//         //     for su in subscription.clone(){
+//         //         let write_tx_clone = write_tx_clone2.lock().await;
+//         //         let message = Message::Text(su.clone());
+//         //         write_tx_clone.unbounded_send(message).unwrap();
+//         //     }
+//         // });
+//
+//
+//         //1 链接
+//
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                                    label.clone(), subscribe_array.clone(),
+//                                                    write_rx, read_tx,
+//                                                    Self::message_text,
+//                                                    Self::message_ping,
+//                                                    Self::message_pong,
+//             ).await {
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:kucoin-现货链接关闭-{:?}",e); }
+//             }
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData
+//     {
+//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//         //订阅 相应
+//         if json_value["type"].as_str() == Option::from("welcome") {
+//             //链接成功
+//             res_data.code = "-200".to_string();
+//             res_data.message = "链接成功,主动发起订阅".to_string();
+//             trace!("链接成功,主动发起订阅:");
+//         } else if json_value["type"].as_str() == Option::from("ack") {
+//             res_data.code = "-201".to_string();
+//             res_data.message = "订阅成功".to_string();
+//         } else if json_value["type"].as_str() == Option::from("error") {
+//             res_data.code = format!("{}", json_value["code"]);
+//             res_data.message = format!("{}", json_value["data"].as_str().unwrap());
+//         } else if json_value.get("topic").is_some() {
+//             res_data.channel = format!("{}", json_value["subject"].as_str().unwrap());
+//
+//             if json_value["topic"].as_str() == Option::from("/contractAccount/wallet") {
+//                 res_data.code = "".to_string();
+//                 if json_value["subject"].as_str() == Option::from("availableBalance.change") {
+//                     res_data.code = "200".to_string();
+//                     res_data.data = json_value["data"].to_string();
+//                 } else {}
+//             } else {
+//                 res_data.data = json_value["data"].to_string();
+//             }
+//         } else {
+//             res_data.code = "".to_string();
+//             res_data.message = "未知解析".to_string();
+//         }
+//         res_data
+//     }
+// }

+ 393 - 393
exchanges/src/kucoin_swap_ws.rs

@@ -1,393 +1,393 @@
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{error, info, trace};
-
-use crate::kucoin_swap_rest::KucoinSwapRest;
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum KucoinSwapWsType {
-    Public,
-    Private,
-}
-
-
-#[derive(Debug)]
-#[derive(Clone)]
-pub struct KucoinSwapWsParam {
-    pub token: String,
-    pub ws_url: String,
-    pub ws_ping_interval: i64,
-    pub ws_ping_timeout: i64,
-    pub is_ok_subscribe: bool,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum KucoinSwapSubscribeType {
-    PuContractMarketLevel2Depth50,
-    //买卖盘 快照,asks:卖,bids:买入
-    PuContractMarketExecution,
-    PuContractMarkettickerV2,
-
-    PrContractAccountWallet,
-    PrContractPosition,
-    PrContractMarketTradeOrdersSys,
-    PrContractMarketTradeOrders,
-}
-
-//账号信息
-#[derive(Clone, Debug)]
-pub struct KucoinSwapLogin {
-    pub access_key: String,
-    pub secret_key: String,
-    pub pass_key: String,
-}
-
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct KucoinSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号
-    login_param: Option<KucoinSwapLogin>,
-    //登陆数据
-    ws_param: KucoinSwapWsParam,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<KucoinSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl KucoinSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub async fn new(is_colo: bool, login_param: Option<KucoinSwapLogin>, ws_type: KucoinSwapWsType) -> KucoinSwapWs {
-        return Self::new_label("default-KucoinSwapWs".to_string(), is_colo, login_param, ws_type).await;
-    }
-    pub async fn new_label(label: String, is_colo: bool, login_param: Option<KucoinSwapLogin>, ws_type: KucoinSwapWsType) -> KucoinSwapWs {
-        /*******公共频道-私有频道数据组装*/
-        let mut ws_param = KucoinSwapWsParam {
-            token: "".to_string(),
-            ws_url: "".to_string(),
-            ws_ping_interval: 0,
-            ws_ping_timeout: 0,
-            is_ok_subscribe: false,
-        };
-
-        /*******公共频道-私有频道数据组装*/
-        let res_data = Self::get_rul_token(ws_type, login_param.clone()).await;
-        let address_url = match res_data {
-            Ok(param) => {
-                ws_param = param;
-                format!("{}?token={}", ws_param.ws_url, ws_param.token)
-            }
-            Err(error) => {
-                error!("-链接地址等参数错误:{:?}", error);
-                "".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-
-        KucoinSwapWs {
-            label,
-            address_url,
-            login_param,
-            ws_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 18,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //根据当前类型获取对应的频道 地址 与 token
-    async fn get_rul_token(ws_type: KucoinSwapWsType, login_param: Option<KucoinSwapLogin>) -> Result<KucoinSwapWsParam, reqwest::Error> {
-        let mut kucoin_exc = KucoinSwapRest::new(false, match login_param {
-            None => {
-                let btree_map: BTreeMap<String, String> = BTreeMap::new();
-                btree_map
-            }
-            Some(d) => {
-                let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-                btree_map.insert("access_key".to_string(), d.access_key);
-                btree_map.insert("secret_key".to_string(), d.secret_key);
-                btree_map.insert("pass_key".to_string(), d.pass_key);
-                btree_map
-            }
-        });
-
-
-        let res_data = match ws_type {
-            KucoinSwapWsType::Public => {
-                kucoin_exc.get_public_token().await
-            }
-            KucoinSwapWsType::Private => {
-                kucoin_exc.get_private_token().await
-            }
-        };
-
-        trace!("kucoin-swap-rest 获取ws连接地址:{:?}",res_data);
-
-        if res_data.code == "200" {
-            let mut ws_url = "".to_string();
-            let mut ws_token = "".to_string();
-            let mut ws_ping_interval: i64 = 0;
-            let mut ws_ping_timeout: i64 = 0;
-
-
-            //数据解析
-            let parsed_json: serde_json::Value = serde_json::from_str(res_data.data.as_str()).unwrap();
-            if let Some(value) = parsed_json.get("token") {
-                let formatted_value = match value {
-                    serde_json::Value::String(s) => s.clone(),
-                    _ => value.to_string()
-                };
-                ws_token = format!("{}", formatted_value);
-            }
-            if let Some(endpoint) = parsed_json["instanceServers"][0]["endpoint"].as_str() {
-                ws_url = format!("{}", endpoint);
-            }
-            if let Some(ping_interval) = parsed_json["instanceServers"][0]["pingInterval"].as_i64() {
-                ws_ping_interval = ping_interval;
-            }
-            if let Some(ping_timeout) = parsed_json["instanceServers"][0]["pingTimeout"].as_i64() {
-                ws_ping_timeout = ping_timeout;
-            }
-
-
-            Ok(KucoinSwapWsParam { ws_url, token: ws_token, ws_ping_interval, ws_ping_timeout, is_ok_subscribe: false })
-        } else {
-            error!("公共/私有-频道获取失败:{:?}", res_data);
-            panic!("公共/私有-频道获取失败:{:?}", res_data);
-        }
-    }
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<KucoinSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 大写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "");
-            *symbol = symbol.replace("-", "");
-        }
-        self.symbol_s = b_array;
-    }
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                KucoinSwapSubscribeType::PuContractMarketLevel2Depth50 => false,
-                KucoinSwapSubscribeType::PuContractMarketExecution => false,
-                KucoinSwapSubscribeType::PuContractMarkettickerV2 => false,
-
-                KucoinSwapSubscribeType::PrContractAccountWallet => true,
-                KucoinSwapSubscribeType::PrContractPosition => true,
-                KucoinSwapSubscribeType::PrContractMarketTradeOrdersSys => true,
-                KucoinSwapSubscribeType::PrContractMarketTradeOrders => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: KucoinSwapSubscribeType) -> serde_json::Value {
-        match subscribe_type {
-            KucoinSwapSubscribeType::PuContractMarketLevel2Depth50 => {//level2
-                serde_json::json!({
-                     "topic": format!("/contractMarket/level2Depth50:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSwapSubscribeType::PuContractMarketExecution => {//match
-                serde_json::json!({
-                     "topic": format!("/contractMarket/execution:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSwapSubscribeType::PuContractMarkettickerV2 => {//tickerV2
-                serde_json::json!({
-                     "topic": format!("/contractMarket/tickerV2:{}", symbol),
-                     "type": "subscribe",
-                     "response": true
-                })
-            }
-            KucoinSwapSubscribeType::PrContractAccountWallet => {//orderMargin.change
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": "/contractAccount/wallet",
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-            KucoinSwapSubscribeType::PrContractPosition => {//position.change
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": format!("/contract/position:{}", symbol),
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-            KucoinSwapSubscribeType::PrContractMarketTradeOrdersSys => {//orderChange
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": format!("/contractMarket/tradeOrders"),
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-            KucoinSwapSubscribeType::PrContractMarketTradeOrders => {//symbolOrderChange
-                serde_json::json!({
-                    "type": "subscribe",
-                    "topic": format!("/contractMarket/tradeOrders:{}", symbol),
-                    "privateChannel":true,
-                    "response":true,
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> Vec<String> {
-        let mut array = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                array.push(ty_str.to_string());
-            }
-        }
-        array
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>,
-    ) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.ws_param.ws_ping_interval.clone();
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = write_tx_am.clone();
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time as u64).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-
-        //设置订阅
-        let subscribe_array = subscription.clone();
-        if login_is {
-            //登录相关
-        }
-
-
-        //1 链接
-
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                                   label.clone(), subscribe_array,
-                                                   write_rx, read_tx,
-                                                   Self::message_text,
-                                                   Self::message_ping,
-                                                   Self::message_pong,
-            ).await {
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:kucoin-期货链接关闭-{:?}",e); }
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData
-    {
-        // trace!("原始数据:{:?}",text);
-        let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-
-        //订阅 相应
-        if json_value["type"].as_str() == Option::from("welcome") {
-            //链接成功
-            res_data.code = "-200".to_string();
-            res_data.message = "链接成功,主动发起订阅".to_string();
-        } else if json_value["type"].as_str() == Option::from("ack") {
-            res_data.code = "-201".to_string();
-            res_data.message = "订阅成功".to_string();
-        } else if json_value["type"].as_str() == Option::from("error") {
-            res_data.code = format!("{}", json_value["code"]);
-            res_data.message = format!("{}", json_value["data"].as_str().unwrap());
-        } else if json_value.get("topic").is_some() {
-            res_data.channel = format!("{}", json_value["subject"].as_str().unwrap());
-
-            if json_value["topic"].as_str() == Option::from("/contractAccount/wallet") {
-                res_data.code = "".to_string();
-                if json_value["subject"].as_str() == Option::from("availableBalance.change") {
-                    res_data.code = "200".to_string();
-                    res_data.data = json_value["data"].to_string();
-                } else {}
-            } else {
-                res_data.data = json_value["data"].to_string();
-            }
-        } else {
-            res_data.code = "".to_string();
-            res_data.message = "未知解析".to_string();
-        }
-        res_data
-    }
-}
+// use std::collections::BTreeMap;
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+//
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{error, info, trace};
+//
+// use crate::kucoin_swap_rest::KucoinSwapRest;
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
+//
+// //类型
+// pub enum KucoinSwapWsType {
+//     Public,
+//     Private,
+// }
+//
+//
+// #[derive(Debug)]
+// #[derive(Clone)]
+// pub struct KucoinSwapWsParam {
+//     pub token: String,
+//     pub ws_url: String,
+//     pub ws_ping_interval: i64,
+//     pub ws_ping_timeout: i64,
+//     pub is_ok_subscribe: bool,
+// }
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum KucoinSwapSubscribeType {
+//     PuContractMarketLevel2Depth50,
+//     //买卖盘 快照,asks:卖,bids:买入
+//     PuContractMarketExecution,
+//     PuContractMarkettickerV2,
+//
+//     PrContractAccountWallet,
+//     PrContractPosition,
+//     PrContractMarketTradeOrdersSys,
+//     PrContractMarketTradeOrders,
+// }
+//
+// //账号信息
+// #[derive(Clone, Debug)]
+// pub struct KucoinSwapLogin {
+//     pub access_key: String,
+//     pub secret_key: String,
+//     pub pass_key: String,
+// }
+//
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct KucoinSwapWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //账号
+//     login_param: Option<KucoinSwapLogin>,
+//     //登陆数据
+//     ws_param: KucoinSwapWsParam,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<KucoinSwapSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl KucoinSwapWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub async fn new(is_colo: bool, login_param: Option<KucoinSwapLogin>, ws_type: KucoinSwapWsType) -> KucoinSwapWs {
+//         return Self::new_label("default-KucoinSwapWs".to_string(), is_colo, login_param, ws_type).await;
+//     }
+//     pub async fn new_label(label: String, is_colo: bool, login_param: Option<KucoinSwapLogin>, ws_type: KucoinSwapWsType) -> KucoinSwapWs {
+//         /*******公共频道-私有频道数据组装*/
+//         let mut ws_param = KucoinSwapWsParam {
+//             token: "".to_string(),
+//             ws_url: "".to_string(),
+//             ws_ping_interval: 0,
+//             ws_ping_timeout: 0,
+//             is_ok_subscribe: false,
+//         };
+//
+//         /*******公共频道-私有频道数据组装*/
+//         let res_data = Self::get_rul_token(ws_type, login_param.clone()).await;
+//         let address_url = match res_data {
+//             Ok(param) => {
+//                 ws_param = param;
+//                 format!("{}?token={}", ws_param.ws_url, ws_param.token)
+//             }
+//             Err(error) => {
+//                 error!("-链接地址等参数错误:{:?}", error);
+//                 "".to_string()
+//             }
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",address_url);
+//         } else {
+//             info!("走普通通道:{}",address_url);
+//         }
+//
+//         KucoinSwapWs {
+//             label,
+//             address_url,
+//             login_param,
+//             ws_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 18,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //根据当前类型获取对应的频道 地址 与 token
+//     async fn get_rul_token(ws_type: KucoinSwapWsType, login_param: Option<KucoinSwapLogin>) -> Result<KucoinSwapWsParam, reqwest::Error> {
+//         let mut kucoin_exc = KucoinSwapRest::new(false, match login_param {
+//             None => {
+//                 let btree_map: BTreeMap<String, String> = BTreeMap::new();
+//                 btree_map
+//             }
+//             Some(d) => {
+//                 let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
+//                 btree_map.insert("access_key".to_string(), d.access_key);
+//                 btree_map.insert("secret_key".to_string(), d.secret_key);
+//                 btree_map.insert("pass_key".to_string(), d.pass_key);
+//                 btree_map
+//             }
+//         });
+//
+//
+//         let res_data = match ws_type {
+//             KucoinSwapWsType::Public => {
+//                 kucoin_exc.get_public_token().await
+//             }
+//             KucoinSwapWsType::Private => {
+//                 kucoin_exc.get_private_token().await
+//             }
+//         };
+//
+//         trace!("kucoin-swap-rest 获取ws连接地址:{:?}",res_data);
+//
+//         if res_data.code == "200" {
+//             let mut ws_url = "".to_string();
+//             let mut ws_token = "".to_string();
+//             let mut ws_ping_interval: i64 = 0;
+//             let mut ws_ping_timeout: i64 = 0;
+//
+//
+//             //数据解析
+//             let parsed_json: serde_json::Value = serde_json::from_str(res_data.data.as_str()).unwrap();
+//             if let Some(value) = parsed_json.get("token") {
+//                 let formatted_value = match value {
+//                     serde_json::Value::String(s) => s.clone(),
+//                     _ => value.to_string()
+//                 };
+//                 ws_token = format!("{}", formatted_value);
+//             }
+//             if let Some(endpoint) = parsed_json["instanceServers"][0]["endpoint"].as_str() {
+//                 ws_url = format!("{}", endpoint);
+//             }
+//             if let Some(ping_interval) = parsed_json["instanceServers"][0]["pingInterval"].as_i64() {
+//                 ws_ping_interval = ping_interval;
+//             }
+//             if let Some(ping_timeout) = parsed_json["instanceServers"][0]["pingTimeout"].as_i64() {
+//                 ws_ping_timeout = ping_timeout;
+//             }
+//
+//
+//             Ok(KucoinSwapWsParam { ws_url, token: ws_token, ws_ping_interval, ws_ping_timeout, is_ok_subscribe: false })
+//         } else {
+//             error!("公共/私有-频道获取失败:{:?}", res_data);
+//             panic!("公共/私有-频道获取失败:{:?}", res_data);
+//         }
+//     }
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<KucoinSwapSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 大写
+//             *symbol = symbol.to_uppercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("_", "");
+//             *symbol = symbol.replace("-", "");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 KucoinSwapSubscribeType::PuContractMarketLevel2Depth50 => false,
+//                 KucoinSwapSubscribeType::PuContractMarketExecution => false,
+//                 KucoinSwapSubscribeType::PuContractMarkettickerV2 => false,
+//
+//                 KucoinSwapSubscribeType::PrContractAccountWallet => true,
+//                 KucoinSwapSubscribeType::PrContractPosition => true,
+//                 KucoinSwapSubscribeType::PrContractMarketTradeOrdersSys => true,
+//                 KucoinSwapSubscribeType::PrContractMarketTradeOrders => true,
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: KucoinSwapSubscribeType) -> serde_json::Value {
+//         match subscribe_type {
+//             KucoinSwapSubscribeType::PuContractMarketLevel2Depth50 => {//level2
+//                 serde_json::json!({
+//                      "topic": format!("/contractMarket/level2Depth50:{}", symbol),
+//                      "type": "subscribe",
+//                      "response": true
+//                 })
+//             }
+//             KucoinSwapSubscribeType::PuContractMarketExecution => {//match
+//                 serde_json::json!({
+//                      "topic": format!("/contractMarket/execution:{}", symbol),
+//                      "type": "subscribe",
+//                      "response": true
+//                 })
+//             }
+//             KucoinSwapSubscribeType::PuContractMarkettickerV2 => {//tickerV2
+//                 serde_json::json!({
+//                      "topic": format!("/contractMarket/tickerV2:{}", symbol),
+//                      "type": "subscribe",
+//                      "response": true
+//                 })
+//             }
+//             KucoinSwapSubscribeType::PrContractAccountWallet => {//orderMargin.change
+//                 serde_json::json!({
+//                     "type": "subscribe",
+//                     "topic": "/contractAccount/wallet",
+//                     "privateChannel":true,
+//                     "response":true,
+//                 })
+//             }
+//             KucoinSwapSubscribeType::PrContractPosition => {//position.change
+//                 serde_json::json!({
+//                     "type": "subscribe",
+//                     "topic": format!("/contract/position:{}", symbol),
+//                     "privateChannel":true,
+//                     "response":true,
+//                 })
+//             }
+//             KucoinSwapSubscribeType::PrContractMarketTradeOrdersSys => {//orderChange
+//                 serde_json::json!({
+//                     "type": "subscribe",
+//                     "topic": format!("/contractMarket/tradeOrders"),
+//                     "privateChannel":true,
+//                     "response":true,
+//                 })
+//             }
+//             KucoinSwapSubscribeType::PrContractMarketTradeOrders => {//symbolOrderChange
+//                 serde_json::json!({
+//                     "type": "subscribe",
+//                     "topic": format!("/contractMarket/tradeOrders:{}", symbol),
+//                     "privateChannel":true,
+//                     "response":true,
+//                 })
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> Vec<String> {
+//         let mut array = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
+//                 array.push(ty_str.to_string());
+//             }
+//         }
+//         array
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>,
+//     ) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         let heartbeat_time = self.ws_param.ws_ping_interval.clone();
+//
+//         //心跳-- 方法内部线程启动
+//         let write_tx_clone1 = write_tx_am.clone();
+//         tokio::spawn(async move {
+//             trace!("线程-异步心跳-开始");
+//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time as u64).await;
+//             trace!("线程-异步心跳-结束");
+//         });
+//
+//
+//         //设置订阅
+//         let subscribe_array = subscription.clone();
+//         if login_is {
+//             //登录相关
+//         }
+//
+//
+//         //1 链接
+//
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                                    label.clone(), subscribe_array,
+//                                                    write_rx, read_tx,
+//                                                    Self::message_text,
+//                                                    Self::message_ping,
+//                                                    Self::message_pong,
+//             ).await {
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:kucoin-期货链接关闭-{:?}",e); }
+//             }
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData
+//     {
+//         // trace!("原始数据:{:?}",text);
+//         let mut res_data = ResponseData::new("".to_string(), "200".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//
+//         //订阅 相应
+//         if json_value["type"].as_str() == Option::from("welcome") {
+//             //链接成功
+//             res_data.code = "-200".to_string();
+//             res_data.message = "链接成功,主动发起订阅".to_string();
+//         } else if json_value["type"].as_str() == Option::from("ack") {
+//             res_data.code = "-201".to_string();
+//             res_data.message = "订阅成功".to_string();
+//         } else if json_value["type"].as_str() == Option::from("error") {
+//             res_data.code = format!("{}", json_value["code"]);
+//             res_data.message = format!("{}", json_value["data"].as_str().unwrap());
+//         } else if json_value.get("topic").is_some() {
+//             res_data.channel = format!("{}", json_value["subject"].as_str().unwrap());
+//
+//             if json_value["topic"].as_str() == Option::from("/contractAccount/wallet") {
+//                 res_data.code = "".to_string();
+//                 if json_value["subject"].as_str() == Option::from("availableBalance.change") {
+//                     res_data.code = "200".to_string();
+//                     res_data.data = json_value["data"].to_string();
+//                 } else {}
+//             } else {
+//                 res_data.data = json_value["data"].to_string();
+//             }
+//         } else {
+//             res_data.code = "".to_string();
+//             res_data.message = "未知解析".to_string();
+//         }
+//         res_data
+//     }
+// }

+ 371 - 371
exchanges/src/okx_swap_ws.rs

@@ -1,371 +1,371 @@
-use std::sync::Arc;
-use std::sync::atomic::AtomicBool;
-use std::time::Duration;
-
-use chrono::Utc;
-use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use ring::hmac;
-use serde_json::{json, Value};
-use tokio::sync::Mutex;
-use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{info, trace};
-
-use crate::response_base::ResponseData;
-use crate::socket_tool::{AbstractWsMode, HeartbeatType};
-
-//类型
-pub enum OkxSwapWsType {
-    //订阅频道类型
-    Public,
-    Private,
-    Business,
-}
-
-//订阅频道
-#[derive(Clone)]
-pub enum OkxSwapSubscribeType {
-    PuIndexTickers,
-    PuBooks5,
-    Putrades,
-    PuBooks50L2tbt,
-
-    BuIndexCandle30m,
-
-    PrBalanceAndPosition,
-    PrAccount(String),
-    PrOrders,
-    PrPositions,
-
-}
-
-//账号信息
-#[derive(Clone)]
-#[allow(dead_code)]
-pub struct OkxSwapLogin {
-    pub api_key: String,
-    pub secret_key: String,
-    pub passphrase: String,
-}
-
-#[derive(Clone)]
-pub struct OkxSwapWs {
-    //类型
-    label: String,
-    //地址
-    address_url: String,
-    //账号信息
-    login_param: Option<OkxSwapLogin>,
-    //币对
-    symbol_s: Vec<String>,
-    //订阅
-    subscribe_types: Vec<OkxSwapSubscribeType>,
-    //心跳间隔
-    heartbeat_time: u64,
-}
-
-impl OkxSwapWs {
-    /*******************************************************************************************************/
-    /*****************************************获取一个对象****************************************************/
-    /*******************************************************************************************************/
-    pub fn new(is_colo: bool, login_param: Option<OkxSwapLogin>, ws_type: OkxSwapWsType) -> OkxSwapWs {
-        return OkxSwapWs::new_label("default-OkxSwapWs".to_string(), is_colo, login_param, ws_type);
-    }
-    pub fn new_label(label: String, is_colo: bool, login_param: Option<OkxSwapLogin>, ws_type: OkxSwapWsType) -> OkxSwapWs {
-        /*******公共频道-私有频道数据组装*/
-        let address_url = match ws_type {
-            OkxSwapWsType::Public => {
-                "wss://ws.okx.com:8443/ws/v5/public".to_string()
-            }
-            OkxSwapWsType::Private => {
-                "wss://ws.okx.com:8443/ws/v5/private".to_string()
-            }
-            OkxSwapWsType::Business => {
-                "wss://ws.okx.com:8443/ws/v5/business".to_string()
-            }
-        };
-
-        if is_colo {
-            info!("开启高速(未配置,走普通:{})通道",address_url);
-        } else {
-            info!("走普通通道:{}",address_url);
-        }
-        /*****返回结构体*******/
-        OkxSwapWs {
-            label,
-            address_url,
-            login_param,
-            symbol_s: vec![],
-            subscribe_types: vec![],
-            heartbeat_time: 1000 * 10,
-        }
-    }
-
-    /*******************************************************************************************************/
-    /*****************************************订阅函数********************************************************/
-    /*******************************************************************************************************/
-    //手动添加订阅信息
-    pub fn set_subscribe(&mut self, subscribe_types: Vec<OkxSwapSubscribeType>) {
-        self.subscribe_types.extend(subscribe_types);
-    }
-    //手动添加币对
-    pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
-        for symbol in b_array.iter_mut() {
-            // 小写
-            *symbol = symbol.to_uppercase();
-            // 字符串替换
-            *symbol = symbol.replace("_", "-");
-        }
-        self.symbol_s = b_array;
-    }
-    //频道是否需要登录
-    fn contains_pr(&self) -> bool {
-        for t in self.subscribe_types.clone() {
-            if match t {
-                OkxSwapSubscribeType::PuIndexTickers => false,
-                OkxSwapSubscribeType::PuBooks5 => false,
-                OkxSwapSubscribeType::Putrades => false,
-                OkxSwapSubscribeType::PuBooks50L2tbt => false,
-
-                OkxSwapSubscribeType::BuIndexCandle30m => false,
-
-                OkxSwapSubscribeType::PrBalanceAndPosition => true,
-                OkxSwapSubscribeType::PrAccount(_) => true,
-                OkxSwapSubscribeType::PrOrders => true,
-                OkxSwapSubscribeType::PrPositions => true,
-            } {
-                return true;
-            }
-        }
-        false
-    }
-    /*******************************************************************************************************/
-    /*****************************************工具函数********************************************************/
-    /*******************************************************************************************************/
-    //订阅枚举解析
-    pub fn enum_to_string(symbol: String, subscribe_type: OkxSwapSubscribeType) -> Value {
-        match subscribe_type {
-            OkxSwapSubscribeType::PuIndexTickers => {
-                json!({
-                    "channel":"index-tickers",
-                    "instId":symbol
-                })
-            }
-
-            OkxSwapSubscribeType::PuBooks5 => {
-                json!({
-                    "channel":"books5",
-                    "instId":symbol
-                })
-            }
-            OkxSwapSubscribeType::Putrades => {
-                json!({
-                    "channel":"trades",
-                    "instId":symbol
-                })
-            }
-
-            OkxSwapSubscribeType::BuIndexCandle30m => {
-                json!({
-                    "channel":"index-candle30m",
-                    "instId":symbol
-                })
-            }
-
-            OkxSwapSubscribeType::PrAccount(ccy) => {
-                json!({
-                    "channel":"account",
-                    "ccy":ccy
-                })
-            }
-            OkxSwapSubscribeType::PuBooks50L2tbt => {
-                json!({
-                    "channel":"books50-l2-tbt",
-                    "instId":symbol
-                })
-            }
-            OkxSwapSubscribeType::PrBalanceAndPosition => {
-                json!({
-                    "channel":"balance_and_position"
-                })
-            }
-            OkxSwapSubscribeType::PrOrders => {
-                json!({
-                    "channel":"orders",
-                    "instType":"SWAP",
-                    "instFamily":symbol
-                })
-            }
-            OkxSwapSubscribeType::PrPositions => {
-                json!({
-                    "channel":"positions",
-                    "instType":"SWAP",
-                })
-            }
-        }
-    }
-    //订阅信息生成
-    pub fn get_subscription(&self) -> String {
-        let mut args = vec![];
-        for symbol in &self.symbol_s {
-            for subscribe_type in &self.subscribe_types {
-                let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
-                args.push(ty_str);
-            }
-        }
-        let str = json!({
-            "op": "subscribe",
-            "args": args
-        });
-
-        // trace!("订阅信息:{}", str.to_string());
-
-        str.to_string()
-    }
-    //登录组装
-    fn log_in_to_str(login_param: Option<OkxSwapLogin>) -> String {
-        let mut login_json_str = "".to_string();
-
-        let mut access_key: String = "".to_string();
-        let mut secret_key: String = "".to_string();
-        let mut passphrase: String = "".to_string();
-
-
-        if let Some(param) = login_param {
-            access_key = param.api_key;
-            secret_key = param.secret_key;
-            passphrase = param.passphrase;
-        }
-
-        if access_key.len() > 0 || secret_key.len() > 0 || passphrase.len() > 0 {
-            let timestamp = Utc::now().timestamp().to_string();
-            // 时间戳 + 请求类型+ 请求参数字符串
-            let message = format!("{}GET{}", timestamp, "/users/self/verify");
-            let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
-            let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
-            let sign = base64::encode(result);
-
-            let login_json = json!({
-                              "op": "login",
-                                "args": [{
-                                "apiKey": access_key,
-                                "passphrase": passphrase,
-                                "timestamp": timestamp,
-                                "sign": sign  }]
-                        });
-
-            trace!("---login_json:{0}", login_json.to_string());
-            trace!("--登陆:{}", login_json.to_string());
-            login_json_str = login_json.to_string();
-        }
-        login_json_str
-    }
-    /*******************************************************************************************************/
-    /*****************************************socket基本*****************************************************/
-    /*******************************************************************************************************/
-    //链接
-    pub async fn ws_connect_async(&mut self,
-                                  bool_v1: Arc<AtomicBool>,
-                                  write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
-                                  write_rx: UnboundedReceiver<Message>,
-                                  read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
-    {
-        let login_is = self.contains_pr();
-        let subscription = self.get_subscription();
-        let address_url = self.address_url.clone();
-        let label = self.label.clone();
-        let heartbeat_time = self.heartbeat_time.clone();
-
-
-        //心跳-- 方法内部线程启动
-        let write_tx_clone1 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            trace!("线程-异步心跳-开始");
-            AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
-            trace!("线程-异步心跳-结束");
-        });
-
-        //设置订阅
-        let  subscribe_array = vec![];
-        if login_is {
-            let write_tx_clone2 = Arc::clone(write_tx_am);
-            let login_str = Self::log_in_to_str(self.login_param.clone());
-            tokio::spawn(async move {
-                //登录相关
-                AbstractWsMode::send_subscribe(write_tx_clone2, Message::Text(login_str)).await;
-            });
-        }
-        let write_tx_clone3 = Arc::clone(write_tx_am);
-        tokio::spawn(async move {
-            tokio::time::sleep(Duration::from_millis(3 * 1000)).await;
-            //登录相关
-            AbstractWsMode::send_subscribe(write_tx_clone3, Message::Text(subscription)).await;
-        });
-
-        //链接
-        let t2 = tokio::spawn(async move {
-            trace!("线程-异步链接-开始");
-            match AbstractWsMode::ws_connect_async(bool_v1, address_url.clone(),
-                                             label.clone(), subscribe_array,
-                                             write_rx, read_tx,
-                                             Self::message_text,
-                                             Self::message_ping,
-                                             Self::message_pong,
-            ).await{
-                Ok(_) => { trace!("线程-异步链接-结束"); }
-                Err(e) => { trace!("发生异常:okx-期货链接关闭-{:?}",e); }
-            }
-        });
-        tokio::try_join!(t2).unwrap();
-        trace!("线程-心跳与链接-结束");
-
-        Ok(())
-    }
-    /*******************************************************************************************************/
-    /*****************************************数据解析*****************************************************/
-    /*******************************************************************************************************/
-    //数据解析-Text
-    pub fn message_text(text: String) -> Option<ResponseData> {
-        let  response_data = Self::ok_text(text);
-        Option::from(response_data)
-    }
-    //数据解析-ping
-    pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析-pong
-    pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
-        return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
-    }
-    //数据解析
-    pub fn ok_text(text: String) -> ResponseData
-    {
-        // trace!("元数据:{}",text);
-        let mut res_data = ResponseData::new("".to_string(), "".to_string(), "success".to_string(), "".to_string());
-        let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
-        if json_value.get("event").is_some() {//订阅返回
-            if json_value["event"].as_str() == Option::from("login") &&
-                json_value["code"].as_str() == Option::from("0") {
-                res_data.code = "-200".to_string();
-                res_data.message = format!("登陆成功!");
-            } else if json_value["event"].as_str() == Option::from("error") {
-                res_data.code = json_value["code"].to_string();
-                res_data.message = format!("订阅失败:{}", json_value["msg"].to_string());
-            } else if json_value["event"].as_str() == Option::from("subscribe") {
-                res_data.code = "-201".to_string();
-                res_data.data = text;
-                res_data.message = format!("订阅成功!");
-            }
-        } else {
-            if json_value.get("arg").is_some() && json_value.get("data").is_some() {
-                res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
-                res_data.data = json_value["data"].to_string();
-                res_data.code = "200".to_string();
-                // res_data.reach_time = json_value["data"][0]["ts"].as_str().unwrap().parse().unwrap()
-            } else {
-                res_data.data = text;
-                res_data.channel = "未知频道".to_string();
-            }
-        }
-        res_data
-    }
-}
+// use std::sync::Arc;
+// use std::sync::atomic::AtomicBool;
+// use std::time::Duration;
+//
+// use chrono::Utc;
+// use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender};
+// use ring::hmac;
+// use serde_json::{json, Value};
+// use tokio::sync::Mutex;
+// use tokio_tungstenite::tungstenite::{Error, Message};
+// use tracing::{info, trace};
+//
+// use crate::response_base::ResponseData;
+// use crate::socket_tool::{AbstractWsMode, HeartbeatType};
+//
+// //类型
+// pub enum OkxSwapWsType {
+//     //订阅频道类型
+//     Public,
+//     Private,
+//     Business,
+// }
+//
+// //订阅频道
+// #[derive(Clone)]
+// pub enum OkxSwapSubscribeType {
+//     PuIndexTickers,
+//     PuBooks5,
+//     Putrades,
+//     PuBooks50L2tbt,
+//
+//     BuIndexCandle30m,
+//
+//     PrBalanceAndPosition,
+//     PrAccount(String),
+//     PrOrders,
+//     PrPositions,
+//
+// }
+//
+// //账号信息
+// #[derive(Clone)]
+// #[allow(dead_code)]
+// pub struct OkxSwapLogin {
+//     pub api_key: String,
+//     pub secret_key: String,
+//     pub passphrase: String,
+// }
+//
+// #[derive(Clone)]
+// pub struct OkxSwapWs {
+//     //类型
+//     label: String,
+//     //地址
+//     address_url: String,
+//     //账号信息
+//     login_param: Option<OkxSwapLogin>,
+//     //币对
+//     symbol_s: Vec<String>,
+//     //订阅
+//     subscribe_types: Vec<OkxSwapSubscribeType>,
+//     //心跳间隔
+//     heartbeat_time: u64,
+// }
+//
+// impl OkxSwapWs {
+//     /*******************************************************************************************************/
+//     /*****************************************获取一个对象****************************************************/
+//     /*******************************************************************************************************/
+//     pub fn new(is_colo: bool, login_param: Option<OkxSwapLogin>, ws_type: OkxSwapWsType) -> OkxSwapWs {
+//         return OkxSwapWs::new_label("default-OkxSwapWs".to_string(), is_colo, login_param, ws_type);
+//     }
+//     pub fn new_label(label: String, is_colo: bool, login_param: Option<OkxSwapLogin>, ws_type: OkxSwapWsType) -> OkxSwapWs {
+//         /*******公共频道-私有频道数据组装*/
+//         let address_url = match ws_type {
+//             OkxSwapWsType::Public => {
+//                 "wss://ws.okx.com:8443/ws/v5/public".to_string()
+//             }
+//             OkxSwapWsType::Private => {
+//                 "wss://ws.okx.com:8443/ws/v5/private".to_string()
+//             }
+//             OkxSwapWsType::Business => {
+//                 "wss://ws.okx.com:8443/ws/v5/business".to_string()
+//             }
+//         };
+//
+//         if is_colo {
+//             info!("开启高速(未配置,走普通:{})通道",address_url);
+//         } else {
+//             info!("走普通通道:{}",address_url);
+//         }
+//         /*****返回结构体*******/
+//         OkxSwapWs {
+//             label,
+//             address_url,
+//             login_param,
+//             symbol_s: vec![],
+//             subscribe_types: vec![],
+//             heartbeat_time: 1000 * 10,
+//         }
+//     }
+//
+//     /*******************************************************************************************************/
+//     /*****************************************订阅函数********************************************************/
+//     /*******************************************************************************************************/
+//     //手动添加订阅信息
+//     pub fn set_subscribe(&mut self, subscribe_types: Vec<OkxSwapSubscribeType>) {
+//         self.subscribe_types.extend(subscribe_types);
+//     }
+//     //手动添加币对
+//     pub fn set_symbols(&mut self, mut b_array: Vec<String>) {
+//         for symbol in b_array.iter_mut() {
+//             // 小写
+//             *symbol = symbol.to_uppercase();
+//             // 字符串替换
+//             *symbol = symbol.replace("_", "-");
+//         }
+//         self.symbol_s = b_array;
+//     }
+//     //频道是否需要登录
+//     fn contains_pr(&self) -> bool {
+//         for t in self.subscribe_types.clone() {
+//             if match t {
+//                 OkxSwapSubscribeType::PuIndexTickers => false,
+//                 OkxSwapSubscribeType::PuBooks5 => false,
+//                 OkxSwapSubscribeType::Putrades => false,
+//                 OkxSwapSubscribeType::PuBooks50L2tbt => false,
+//
+//                 OkxSwapSubscribeType::BuIndexCandle30m => false,
+//
+//                 OkxSwapSubscribeType::PrBalanceAndPosition => true,
+//                 OkxSwapSubscribeType::PrAccount(_) => true,
+//                 OkxSwapSubscribeType::PrOrders => true,
+//                 OkxSwapSubscribeType::PrPositions => true,
+//             } {
+//                 return true;
+//             }
+//         }
+//         false
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************工具函数********************************************************/
+//     /*******************************************************************************************************/
+//     //订阅枚举解析
+//     pub fn enum_to_string(symbol: String, subscribe_type: OkxSwapSubscribeType) -> Value {
+//         match subscribe_type {
+//             OkxSwapSubscribeType::PuIndexTickers => {
+//                 json!({
+//                     "channel":"index-tickers",
+//                     "instId":symbol
+//                 })
+//             }
+//
+//             OkxSwapSubscribeType::PuBooks5 => {
+//                 json!({
+//                     "channel":"books5",
+//                     "instId":symbol
+//                 })
+//             }
+//             OkxSwapSubscribeType::Putrades => {
+//                 json!({
+//                     "channel":"trades",
+//                     "instId":symbol
+//                 })
+//             }
+//
+//             OkxSwapSubscribeType::BuIndexCandle30m => {
+//                 json!({
+//                     "channel":"index-candle30m",
+//                     "instId":symbol
+//                 })
+//             }
+//
+//             OkxSwapSubscribeType::PrAccount(ccy) => {
+//                 json!({
+//                     "channel":"account",
+//                     "ccy":ccy
+//                 })
+//             }
+//             OkxSwapSubscribeType::PuBooks50L2tbt => {
+//                 json!({
+//                     "channel":"books50-l2-tbt",
+//                     "instId":symbol
+//                 })
+//             }
+//             OkxSwapSubscribeType::PrBalanceAndPosition => {
+//                 json!({
+//                     "channel":"balance_and_position"
+//                 })
+//             }
+//             OkxSwapSubscribeType::PrOrders => {
+//                 json!({
+//                     "channel":"orders",
+//                     "instType":"SWAP",
+//                     "instFamily":symbol
+//                 })
+//             }
+//             OkxSwapSubscribeType::PrPositions => {
+//                 json!({
+//                     "channel":"positions",
+//                     "instType":"SWAP",
+//                 })
+//             }
+//         }
+//     }
+//     //订阅信息生成
+//     pub fn get_subscription(&self) -> String {
+//         let mut args = vec![];
+//         for symbol in &self.symbol_s {
+//             for subscribe_type in &self.subscribe_types {
+//                 let ty_str = Self::enum_to_string(symbol.clone(), subscribe_type.clone());
+//                 args.push(ty_str);
+//             }
+//         }
+//         let str = json!({
+//             "op": "subscribe",
+//             "args": args
+//         });
+//
+//         // trace!("订阅信息:{}", str.to_string());
+//
+//         str.to_string()
+//     }
+//     //登录组装
+//     fn log_in_to_str(login_param: Option<OkxSwapLogin>) -> String {
+//         let mut login_json_str = "".to_string();
+//
+//         let mut access_key: String = "".to_string();
+//         let mut secret_key: String = "".to_string();
+//         let mut passphrase: String = "".to_string();
+//
+//
+//         if let Some(param) = login_param {
+//             access_key = param.api_key;
+//             secret_key = param.secret_key;
+//             passphrase = param.passphrase;
+//         }
+//
+//         if access_key.len() > 0 || secret_key.len() > 0 || passphrase.len() > 0 {
+//             let timestamp = Utc::now().timestamp().to_string();
+//             // 时间戳 + 请求类型+ 请求参数字符串
+//             let message = format!("{}GET{}", timestamp, "/users/self/verify");
+//             let hmac_key = ring::hmac::Key::new(hmac::HMAC_SHA256, secret_key.as_bytes());
+//             let result = ring::hmac::sign(&hmac_key, &message.as_bytes());
+//             let sign = base64::encode(result);
+//
+//             let login_json = json!({
+//                               "op": "login",
+//                                 "args": [{
+//                                 "apiKey": access_key,
+//                                 "passphrase": passphrase,
+//                                 "timestamp": timestamp,
+//                                 "sign": sign  }]
+//                         });
+//
+//             trace!("---login_json:{0}", login_json.to_string());
+//             trace!("--登陆:{}", login_json.to_string());
+//             login_json_str = login_json.to_string();
+//         }
+//         login_json_str
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************socket基本*****************************************************/
+//     /*******************************************************************************************************/
+//     //链接
+//     pub async fn ws_connect_async(&mut self,
+//                                   is_shutdown_arc: Arc<AtomicBool>,
+//                                   write_tx_am: &Arc<Mutex<UnboundedSender<Message>>>,
+//                                   write_rx: UnboundedReceiver<Message>,
+//                                   read_tx: UnboundedSender<ResponseData>) -> Result<(), Error>
+//     {
+//         let login_is = self.contains_pr();
+//         let subscription = self.get_subscription();
+//         let address_url = self.address_url.clone();
+//         let label = self.label.clone();
+//         let heartbeat_time = self.heartbeat_time.clone();
+//
+//
+//         //心跳-- 方法内部线程启动
+//         let write_tx_clone1 = Arc::clone(write_tx_am);
+//         tokio::spawn(async move {
+//             trace!("线程-异步心跳-开始");
+//             AbstractWsMode::ping_or_pong(write_tx_clone1, HeartbeatType::Ping, heartbeat_time).await;
+//             trace!("线程-异步心跳-结束");
+//         });
+//
+//         //设置订阅
+//         let  subscribe_array = vec![];
+//         if login_is {
+//             let write_tx_clone2 = Arc::clone(write_tx_am);
+//             let login_str = Self::log_in_to_str(self.login_param.clone());
+//             tokio::spawn(async move {
+//                 //登录相关
+//                 AbstractWsMode::send_subscribe(write_tx_clone2, Message::Text(login_str)).await;
+//             });
+//         }
+//         let write_tx_clone3 = Arc::clone(write_tx_am);
+//         tokio::spawn(async move {
+//             tokio::time::sleep(Duration::from_millis(3 * 1000)).await;
+//             //登录相关
+//             AbstractWsMode::send_subscribe(write_tx_clone3, Message::Text(subscription)).await;
+//         });
+//
+//         //链接
+//         let t2 = tokio::spawn(async move {
+//             trace!("线程-异步链接-开始");
+//             match AbstractWsMode::ws_connect_async(is_shutdown_arc, address_url.clone(),
+//                                              label.clone(), subscribe_array,
+//                                              write_rx, read_tx,
+//                                              Self::message_text,
+//                                              Self::message_ping,
+//                                              Self::message_pong,
+//             ).await{
+//                 Ok(_) => { trace!("线程-异步链接-结束"); }
+//                 Err(e) => { trace!("发生异常:okx-期货链接关闭-{:?}",e); }
+//             }
+//         });
+//         tokio::try_join!(t2).unwrap();
+//         trace!("线程-心跳与链接-结束");
+//
+//         Ok(())
+//     }
+//     /*******************************************************************************************************/
+//     /*****************************************数据解析*****************************************************/
+//     /*******************************************************************************************************/
+//     //数据解析-Text
+//     pub fn message_text(text: String) -> Option<ResponseData> {
+//         let  response_data = Self::ok_text(text);
+//         Option::from(response_data)
+//     }
+//     //数据解析-ping
+//     pub fn message_ping(_pi: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-300".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析-pong
+//     pub fn message_pong(_po: Vec<u8>) -> Option<ResponseData> {
+//         return Option::from(ResponseData::new("".to_string(), "-301".to_string(), "success".to_string(), "".to_string()));
+//     }
+//     //数据解析
+//     pub fn ok_text(text: String) -> ResponseData
+//     {
+//         // trace!("元数据:{}",text);
+//         let mut res_data = ResponseData::new("".to_string(), "".to_string(), "success".to_string(), "".to_string());
+//         let json_value: serde_json::Value = serde_json::from_str(&text).unwrap();
+//         if json_value.get("event").is_some() {//订阅返回
+//             if json_value["event"].as_str() == Option::from("login") &&
+//                 json_value["code"].as_str() == Option::from("0") {
+//                 res_data.code = "-200".to_string();
+//                 res_data.message = format!("登陆成功!");
+//             } else if json_value["event"].as_str() == Option::from("error") {
+//                 res_data.code = json_value["code"].to_string();
+//                 res_data.message = format!("订阅失败:{}", json_value["msg"].to_string());
+//             } else if json_value["event"].as_str() == Option::from("subscribe") {
+//                 res_data.code = "-201".to_string();
+//                 res_data.data = text;
+//                 res_data.message = format!("订阅成功!");
+//             }
+//         } else {
+//             if json_value.get("arg").is_some() && json_value.get("data").is_some() {
+//                 res_data.channel = format!("{}", json_value["arg"]["channel"].as_str().unwrap());
+//                 res_data.data = json_value["data"].to_string();
+//                 res_data.code = "200".to_string();
+//                 // res_data.reach_time = json_value["data"][0]["ts"].as_str().unwrap().parse().unwrap()
+//             } else {
+//                 res_data.data = text;
+//                 res_data.channel = "未知频道".to_string();
+//             }
+//         }
+//         res_data
+//     }
+// }

+ 123 - 193
exchanges/src/socket_tool.rs

@@ -13,7 +13,7 @@ use tokio::net::TcpStream;
 use tokio::sync::Mutex;
 use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
 use tokio_tungstenite::tungstenite::{Error, Message};
-use tracing::{trace};
+use tracing::{info, trace};
 
 use crate::proxy;
 use crate::proxy::{ProxyEnum, ProxyResponseEnum};
@@ -29,13 +29,121 @@ pub enum HeartbeatType {
 pub struct AbstractWsMode {}
 
 impl AbstractWsMode {
+    pub async fn ws_connected<T, PI, PO>(write_to_socket_rx_arc: Arc<Mutex<UnboundedReceiver<Message>>>,
+                                         label: String,
+                                         is_shutdown_arc: Arc<AtomicBool>,
+                                         subscribe_array: Vec<String>,
+                                         ws_stream: WebSocketStream<MaybeTlsStream<TcpStream>>,
+                                         message_text: T,
+                                         message_ping: PI,
+                                         message_pong: PO)
+        where T: Fn(String) -> Option<ResponseData> + Copy,
+              PI: Fn(Vec<u8>) -> Option<ResponseData> + Copy,
+              PO: Fn(Vec<u8>) -> Option<ResponseData> + Copy
+    {
+        info!("WebSocket 建立链接成功。");
+        let (ws_write, mut ws_read) = ws_stream.split();
+        let ws_write_arc = Arc::new(Mutex::new(ws_write));
+
+        // 将socket 的写操作与【写通道(外部向socket写)】链接起来,将数据以ok的结构体封装进行传递
+        // 这里是形成链式操作,如果要将外界的信息传进来(使用socket查单、下单之类的,部分交易所可以支持),就要这要弄
+        let mut write_to_socket_rx = write_to_socket_rx_arc.lock().await;
+        let ws_write_channel_clone = Arc::clone(&ws_write_arc);
+        let stdin_to_ws = async {
+            while let Some(message) = write_to_socket_rx.next().await {
+                let mut write_lock2 = ws_write_channel_clone.lock().await;
+                write_lock2.send(message).await?;
+            }
+            Ok::<(), Error>(())
+        };
+
+        // 订阅消息
+        info!("订阅内容:{:?}", subscribe_array.clone());
+        for s in &subscribe_array {
+            let mut write_lock = ws_write_arc.lock().await;
+            write_lock.send(Message::Text(s.parse().unwrap())).await.expect("订阅消息失败");
+        }
+
+        let ws_write_inner = Arc::clone(&ws_write_arc);
+        let ws_to_stdout = async {
+            while let Some(message) = ws_read.next().await {
+                if !is_shutdown_arc.load(Ordering::Relaxed) {
+                    continue;
+                }
+
+                let response_data = AbstractWsMode::analysis_message(message, message_text, message_ping, message_pong);
+                // let response_data = func(message);
+                if response_data.is_some() {
+                    let mut data = response_data.unwrap();
+                    data.label = label.clone();
+                    data.time = chrono::Utc::now().timestamp_micros();
+
+                    let code = data.code.clone();
+                    /*
+                        200 -正确返回
+                       -200 -登录成功
+                       -201 -订阅成功
+                       -300 -客户端收到服务器心跳ping,需要响应
+                       -301 -客户端收到服务器心跳pong,需要响应
+                       -302 -客户端收到服务器心跳自定义,需要响应自定义
+                    */
+                    match code.as_str() {
+                        "200" => {
+                            // read_tx.unbounded_send(data).unwrap();
+                        }
+                        "-200" => {
+                            //登录成功
+                            trace!("登录成功:{:?}", data);
+                        }
+                        "-201" => {
+                            //订阅成功
+                            trace!("订阅成功:{:?}", data);
+                        }
+                        "-300" => {
+                            //服务器发送心跳 ping 给客户端,客户端需要pong回应
+                            trace!("服务器响应-ping");
+                            if data.data.len() > 0 {
+                                let mut ws_write = ws_write_inner.lock().await;
+                                ws_write.send(Message::Pong(Vec::from(data.data))).await?;
+                                trace!("客户端回应服务器-pong");
+                            }
+                        }
+                        "-301" => {
+                            //服务器发送心跳 pong 给客户端,客户端需要ping回应
+                            trace!("服务器响应-pong");
+                            if data.data.len() > 0 {
+                                let mut ws_write = ws_write_inner.lock().await;
+                                ws_write.send(Message::Ping(Vec::from(data.data))).await?;
+                                trace!("客户端回应服务器-ping");
+                            }
+                        }
+                        "-302" => {
+                            //客户端收到服务器心跳自定义,需要响应自定义
+                            trace!("特定字符心跳,特殊响应:{:?}", data);
+                            let mut ws_write = ws_write_inner.lock().await;
+                            ws_write.send(Message::Text(data.data)).await?;
+                            trace!("特殊字符心跳-回应完成");
+                        }
+                        _ => {
+                            trace!("未知:{:?}",data);
+                        }
+                    }
+                }
+            }
+            Ok::<(), Error>(())
+        };
+
+        //必须操作。,因为不同于其他的高级语言,有自动内存管理,所以为了防范地址改变,所以需要做此处理
+        pin_mut!(stdin_to_ws, ws_to_stdout,);
+        future::select(stdin_to_ws, ws_to_stdout).await;
+    }
+
     //创建链接
-    pub async fn ws_connect_async<T, PI, PO>(bool_v1: Arc<AtomicBool>,
+    pub async fn ws_connect_async<T, PI, PO>(is_shutdown_arc: Arc<AtomicBool>,
                                              address_url: String,
-                                             lable: String,
+                                             label: String,
                                              subscribe_array: Vec<String>,
-                                             mut write_rx: UnboundedReceiver<Message>,
-                                             read_tx: UnboundedSender<ResponseData>,
+                                             write_to_socket_rx: UnboundedReceiver<Message>,
                                              message_text: T,
                                              message_ping: PI,
                                              message_pong: PO) -> Result<(), Error>
@@ -56,102 +164,19 @@ impl AbstractWsMode {
             }
         };
 
+        let write_to_socket_rx_arc = Arc::new(Mutex::new(write_to_socket_rx));
+
         loop {
             match connect_async(address_url.clone(), proxy).await {
                 Ok((ws_stream, _)) => {
-                    trace!("WebSocket 握手完成。");
-                    let (write, mut read) = ws_stream.split();
-
-                    let write_arc = Arc::new(Mutex::new(write));
-                    let write_clone = Arc::clone(&write_arc);
-                    //订阅写入(包括订阅信息 )
-                    trace!("订阅内容:{:?}",subscribe_array.clone());
-                    for s in &subscribe_array {
-                        let mut write_lock = write_clone.lock().await;
-                        write_lock.send(Message::Text(s.parse().unwrap())).await?;
-                    }
-
-                    //将socket 的写操作与 写通道链接起来,将数据以ok的结构体封装进行传递
-                    // let stdin_to_ws = write_rx.map(Ok).forward(write);
-                    // Writing task
-                    let write_clone2 = Arc::clone(&write_arc);
-                    let stdin_to_ws = async {
-                        while let Some(message) = write_rx.next().await {
-                            let mut write_lock2 = write_clone2.lock().await;
-                            write_lock2.send(message).await?;
-                        }
-                        Ok::<(), Error>(())
-                    };
-                    let write_clone3 = Arc::clone(&write_arc);
-                    let ws_to_stdout = async {
-                        while let Some(message) = read.next().await {
-                            if !bool_v1.load(Ordering::Relaxed) {
-                                continue;
-                            }
-
-                            let mut write_lock3 = write_clone3.lock().await;
-                            let response_data = AbstractWsMode::analysis_message(message, message_text, message_ping, message_pong);
-                            // let response_data = func(message);
-                            if response_data.is_some() {
-                                let mut data = response_data.unwrap();
-                                data.label = lable.clone();
-                                data.time = chrono::Utc::now().timestamp_micros();
-
-                                let code = data.code.clone();
-                                /*
-                                    200 -正确返回
-                                   -200 -登录成功
-                                   -201 -订阅成功
-                                   -300 -客户端收到服务器心跳ping,需要响应
-                                   -301 -客户端收到服务器心跳pong,需要响应
-                                   -302 -客户端收到服务器心跳自定义,需要响应自定义
-                                */
-                                match code.as_str() {
-                                    "200" => {
-                                        read_tx.unbounded_send(data).unwrap();
-                                    }
-                                    "-200" => {
-                                        //登录成功
-                                        trace!("登录成功:{:?}", data);
-                                    }
-                                    "-201" => {
-                                        //订阅成功
-                                        trace!("订阅成功:{:?}", data);
-                                    }
-                                    "-300" => {
-                                        //服务器发送心跳 ping 给客户端,客户端需要pong回应
-                                        trace!("服务器响应-ping");
-                                        if data.data.len() > 0 {
-                                            write_lock3.send(Message::Pong(Vec::from(data.data))).await?;
-                                            trace!("客户端回应服务器-pong");
-                                        }
-                                    }
-                                    "-301" => {
-                                        //服务器发送心跳 pong 给客户端,客户端需要ping回应
-                                        trace!("服务器响应-pong");
-                                        if data.data.len() > 0 {
-                                            write_lock3.send(Message::Ping(Vec::from(data.data))).await?;
-                                            trace!("客户端回应服务器-ping");
-                                        }
-                                    }
-                                    "-302" => {
-                                        //客户端收到服务器心跳自定义,需要响应自定义
-                                        trace!("特定字符心跳,特殊响应:{:?}", data);
-                                        write_lock3.send(Message::Text(data.data)).await?;
-                                        trace!("特殊字符心跳-回应完成");
-                                    }
-                                    _ => {
-                                        trace!("未知:{:?}",data);
-                                    }
-                                }
-                            }
-                        }
-                        Ok::<(), Error>(())
-                    };
-
-                    //必须操作。,因为不同于其他的高级语言,有自动内存管理,所以为了防范地址改变,所以需要做此处理
-                    pin_mut!(stdin_to_ws, ws_to_stdout,);
-                    future::select(stdin_to_ws, ws_to_stdout).await;
+                    Self::ws_connected(write_to_socket_rx_arc.clone(),
+                                       label.clone(),
+                                       is_shutdown_arc.clone(),
+                                       subscribe_array.clone(),
+                                       ws_stream,
+                                       message_text,
+                                       message_ping,
+                                       message_pong).await;
                 }
                 Err(e) => {
                     trace!("WebSocket 握手失败:{:?}",e);
@@ -160,102 +185,7 @@ impl AbstractWsMode {
             trace!("---5");
             trace!("---4");
             trace!("重启...");
-
-            // let (ws_stream, _) = connect_async(address_url.clone(), proxy).await.unwrap();
-            // trace!("WebSocket 握手完成。");
-            // let (write, mut read) = ws_stream.split();
-            //
-            // let write_arc = Arc::new(Mutex::new(write));
-            // let write_clone = Arc::clone(&write_arc);
-            // //订阅写入(包括订阅信息 )
-            // trace!("订阅内容:{:?}",subscribe_array.clone());
-            // for s in &subscribe_array {
-            //     let mut write_lock = write_clone.lock().await;
-            //     write_lock.send(Message::Text(s.parse().unwrap())).await?;
-            // }
-            //
-            // //将socket 的写操作与 写通道链接起来,将数据以ok的结构体封装进行传递
-            // // let stdin_to_ws = write_rx.map(Ok).forward(write);
-            // // Writing task
-            // let write_clone2 = Arc::clone(&write_arc);
-            // let stdin_to_ws = async {
-            //     while let Some(message) = write_rx.next().await {
-            //         let mut write_lock2 = write_clone2.lock().await;
-            //         write_lock2.send(message).await?;
-            //     }
-            //     Ok::<(), tokio_tungstenite::tungstenite::Error>(())
-            // };
-            // let write_clone3 = Arc::clone(&write_arc);
-            // let ws_to_stdout = async {
-            //     while let Some(message) = read.next().await {
-            //         let mut write_lock3 = write_clone3.lock().await;
-            //         let response_data = AbstractWsMode::analysis_message(message, message_text, message_ping, message_pong);
-            //         // let response_data = func(message);
-            //         if response_data.is_some() {
-            //             let mut data = response_data.unwrap();
-            //             data.label = lable.clone();
-            //             let code = data.code.clone();
-            //             /*
-            //                 200 -正确返回
-            //                -200 -登录成功
-            //                -201 -订阅成功
-            //                -300 -客户端收到服务器心跳ping,需要响应
-            //                -301 -客户端收到服务器心跳pong,需要响应
-            //                -302 -客户端收到服务器心跳自定义,需要响应自定义
-            //             */
-            //             match code.as_str() {
-            //                 "200" => {
-            //                     if bool_v1.load(Ordering::Relaxed) {
-            //                         read_tx.unbounded_send(data).unwrap();
-            //                     }
-            //                 }
-            //                 "-200" => {
-            //                     //登录成功
-            //                     trace!("登录成功:{:?}", data);
-            //                 }
-            //                 "-201" => {
-            //                     //订阅成功
-            //                     trace!("订阅成功:{:?}", data);
-            //                 }
-            //                 "-300" => {
-            //                     //服务器发送心跳 ping 给客户端,客户端需要pong回应
-            //                     trace!("服务器响应-ping");
-            //                     if data.data.len() > 0 {
-            //                         write_lock3.send(Message::Pong(Vec::from(data.data))).await?;
-            //                         trace!("客户端回应服务器-pong");
-            //                     }
-            //                 }
-            //                 "-301" => {
-            //                     //服务器发送心跳 pong 给客户端,客户端需要ping回应
-            //                     trace!("服务器响应-pong");
-            //                     if data.data.len() > 0 {
-            //                         write_lock3.send(Message::Ping(Vec::from(data.data))).await?;
-            //                         trace!("客户端回应服务器-ping");
-            //                     }
-            //                 }
-            //                 "-302" => {
-            //                     //客户端收到服务器心跳自定义,需要响应自定义
-            //                     trace!("特定字符心跳,特殊响应:{:?}", data);
-            //                     write_lock3.send(Message::Text(data.data)).await?;
-            //                     trace!("特殊字符心跳-回应完成");
-            //                 }
-            //                 _ => {
-            //                     trace!("未知:{:?}",data);
-            //                 }
-            //             }
-            //         }
-            //     }
-            //     Ok::<(), tokio_tungstenite::tungstenite::Error>(())
-            // };
-            //
-            // //必须操作。,因为不同于其他的高级语言,有自动内存管理,所以为了防范地址改变,所以需要做此处理
-            // pin_mut!(stdin_to_ws, ws_to_stdout,);
-            // future::select(stdin_to_ws, ws_to_stdout).await;
-            // trace!("---5");
-            // trace!("---4");
-            // trace!("重启...");
         }
-        // return Ok(());
     }
 
     //心跳包

+ 4 - 4
exchanges/tests/binance_spot_test.rs

@@ -36,10 +36,10 @@ async fn ws_custom_subscribe() {
     ]);
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -51,7 +51,7 @@ async fn ws_custom_subscribe() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -74,7 +74,7 @@ async fn ws_custom_subscribe() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });

+ 7 - 7
exchanges/tests/binance_swap_test.rs

@@ -38,10 +38,10 @@ async fn ws_custom_subscribe() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         let mut max_delay = 0i64;
@@ -67,7 +67,7 @@ async fn ws_custom_subscribe() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -90,7 +90,7 @@ async fn ws_custom_subscribe() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -109,7 +109,7 @@ async fn ws_custom_subscribe() {
     //************************************
     //11 点31 分
 
-    // let mut bool_v1 = Arc::new(AtomicBool::new(true));
+    // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
     // //创建读写通道
     // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
     // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
@@ -129,10 +129,10 @@ async fn ws_custom_subscribe() {
     //
     //
     // //模拟业务场景 开启链接
-    // let bool_v1_clone = Arc::clone(&bool_v1);
+    // let is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone1 = Arc::clone(&write_tx_am);
     // let t1 = tokio::spawn(async move {
-    //     ws.ws_connect_async(bool_v1_clone, write_tx_clone1, write_rx, &read_tx).await.unwrap();
+    //     ws.ws_connect_async(is_shutdown_arc_clone, write_tx_clone1, write_rx, &read_tx).await.unwrap();
     //     trace!("ws_connect_async 完成");
     // });
     //

+ 9 - 9
exchanges/tests/bitget_spot_test.rs

@@ -21,7 +21,7 @@ async fn ws_custom_subscribe_pu() {
     let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
     let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
 
-    let  bool_v1 = Arc::new(AtomicBool::new(true));
+    let  is_shutdown_arc = Arc::new(AtomicBool::new(true));
     let mut ws = get_ws(None, BitgetSpotWsType::Public).await;
     ws.set_symbols(vec!["BTC_USDT".to_string()]);
     ws.set_subscribe(vec![
@@ -32,10 +32,10 @@ async fn ws_custom_subscribe_pu() {
     ]);
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -47,7 +47,7 @@ async fn ws_custom_subscribe_pu() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -70,7 +70,7 @@ async fn ws_custom_subscribe_pu() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -105,10 +105,10 @@ async fn ws_custom_subscribe_pr() {
     ]);
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
 //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -120,7 +120,7 @@ async fn ws_custom_subscribe_pr() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -143,7 +143,7 @@ async fn ws_custom_subscribe_pr() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });

+ 8 - 8
exchanges/tests/bybit_swap_test.rs

@@ -33,10 +33,10 @@ async fn ws_custom_subscribe_pu() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -48,7 +48,7 @@ async fn ws_custom_subscribe_pu() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -71,7 +71,7 @@ async fn ws_custom_subscribe_pu() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -108,10 +108,10 @@ async fn ws_custom_subscribe_pr() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -123,7 +123,7 @@ async fn ws_custom_subscribe_pr() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -146,7 +146,7 @@ async fn ws_custom_subscribe_pr() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });

+ 4 - 4
exchanges/tests/crypto_spot_test.rs

@@ -29,10 +29,10 @@ async fn ws_pu() {
     ]);
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -44,7 +44,7 @@ async fn ws_pu() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -67,7 +67,7 @@ async fn ws_pu() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });

+ 4 - 4
exchanges/tests/gate_swap_test.rs

@@ -39,10 +39,10 @@ async fn ws_custom_subscribe() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -54,7 +54,7 @@ async fn ws_custom_subscribe() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -77,7 +77,7 @@ async fn ws_custom_subscribe() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });

+ 8 - 8
exchanges/tests/kucoin_spot_test.rs

@@ -31,10 +31,10 @@ async fn ws_custom_subscribe_pu() {
     ]);
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -45,7 +45,7 @@ async fn ws_custom_subscribe_pu() {
     });
 
     //写数据
-    let _bool_v2_clone = Arc::clone(&bool_v1);
+    let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
     let _write_tx_clone = Arc::clone(&write_tx_am);
     // let tw = tokio::spawn(async move {
     //     trace!("线程-数据写入-开始");
@@ -66,7 +66,7 @@ async fn ws_custom_subscribe_pu() {
     // loop {
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -99,10 +99,10 @@ async fn ws_custom_subscribe_pr() {
     ]);
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -113,7 +113,7 @@ async fn ws_custom_subscribe_pr() {
     });
 
     //写数据
-    let _bool_v2_clone = Arc::clone(&bool_v1);
+    let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
     let _write_tx_clone = Arc::clone(&write_tx_am);
     // let tw = tokio::spawn(async move {
     //     trace!("线程-数据写入-开始");
@@ -134,7 +134,7 @@ async fn ws_custom_subscribe_pr() {
     // loop {
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });

+ 8 - 8
exchanges/tests/kucoin_swap_test.rs

@@ -32,10 +32,10 @@ async fn ws_custom_subscribe_pu() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -46,7 +46,7 @@ async fn ws_custom_subscribe_pu() {
     });
 
     //写数据
-    let _bool_v2_clone = Arc::clone(&bool_v1);
+    let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
     let _write_tx_clone = Arc::clone(&write_tx_am);
     // let tw = tokio::spawn(async move {
     //     trace!("线程-数据写入-开始");
@@ -67,7 +67,7 @@ async fn ws_custom_subscribe_pu() {
     // loop {
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -113,10 +113,10 @@ async fn ws_custom_subscribe_pr() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -127,7 +127,7 @@ async fn ws_custom_subscribe_pr() {
     });
 
     //写数据
-    let _bool_v2_clone = Arc::clone(&bool_v1);
+    let _bool_v2_clone = Arc::clone(&is_shutdown_arc);
     let _write_tx_clone = Arc::clone(&write_tx_am);
     // let tw = tokio::spawn(async move {
     //     trace!("线程-数据写入-开始");
@@ -148,7 +148,7 @@ async fn ws_custom_subscribe_pr() {
     // loop {
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });

+ 14 - 14
exchanges/tests/okx_swap_test.rs

@@ -35,10 +35,10 @@ async fn ws_custom_subscribe_pu() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -50,7 +50,7 @@ async fn ws_custom_subscribe_pu() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -73,7 +73,7 @@ async fn ws_custom_subscribe_pu() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -99,10 +99,10 @@ async fn ws_custom_subscribe_bu() {
     ]);
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -114,7 +114,7 @@ async fn ws_custom_subscribe_bu() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -137,7 +137,7 @@ async fn ws_custom_subscribe_bu() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -172,10 +172,10 @@ async fn ws_custom_subscribe_pr() {
 
 
     let write_tx_am = Arc::new(Mutex::new(write_tx));
-    let bool_v1 = Arc::new(AtomicBool::new(true));
+    let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
     //读取
-    let _bool_v1_clone = Arc::clone(&bool_v1);
+    let _is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
     let _tr = tokio::spawn(async move {
         trace!("线程-数据读取-开启");
         loop {
@@ -187,7 +187,7 @@ async fn ws_custom_subscribe_pr() {
     });
 
     //写数据
-    // let bool_v2_clone = Arc::clone(&bool_v1);
+    // let bool_v2_clone = Arc::clone(&is_shutdown_arc);
     // let write_tx_clone = Arc::clone(&write_tx_am);
     // let su = ws.get_subscription();
     // let tw = tokio::spawn(async move {
@@ -210,7 +210,7 @@ async fn ws_custom_subscribe_pr() {
 
     let t1 = tokio::spawn(async move {
         //链接
-        let bool_v3_clone = Arc::clone(&bool_v1);
+        let bool_v3_clone = Arc::clone(&is_shutdown_arc);
         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
         trace!("test 唯一线程结束--");
     });
@@ -220,7 +220,7 @@ async fn ws_custom_subscribe_pr() {
     trace!("参考交易所关闭");
     return;
     //
-    // let mut bool_v1 = Arc::new(AtomicBool::new(true));
+    // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
     // let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
     //
     // btree_map.insert("access_key".to_string(), ACCESS_KEY.to_string());
@@ -237,7 +237,7 @@ async fn ws_custom_subscribe_pr() {
     // ]);
     //
     // let t1 = tokio::spawn(async move {
-    //     ws.custom_subscribe(bool_v1, vec!["BTC-USDT".to_string()]).await;
+    //     ws.custom_subscribe(is_shutdown_arc, vec!["BTC-USDT".to_string()]).await;
     // });
     //
     // let t2 = tokio::spawn(async move {

+ 6 - 6
exchanges/tests/test.rs

@@ -280,7 +280,7 @@ async fn demo_ws_okx_bu() {
 }
 
 async fn demo_ws_kucoin_pr() {
-    // let mut bool_v1 = Arc::new(AtomicBool::new(true));
+    // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
     // let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
     // btree_map.insert("access_key".to_string(), "".to_string());
     // btree_map.insert("secret_key".to_string(), "".to_string());
@@ -292,7 +292,7 @@ async fn demo_ws_kucoin_pr() {
     // ku_ws.set_subscribe(vec![KucoinSubscribeType::PrContractMarketTradeOrdersSys]);
     //
     // let t1 = tokio::spawn(async move {
-    //     ku_ws.custom_subscribe(bool_v1, vec!["ACHUSDTM".to_string(), "ROSEUSDTM".to_string()]).await;
+    //     ku_ws.custom_subscribe(is_shutdown_arc, vec!["ACHUSDTM".to_string(), "ROSEUSDTM".to_string()]).await;
     // });
     //
     // let t2 = tokio::spawn(async move {
@@ -307,7 +307,7 @@ async fn demo_ws_kucoin_pr() {
 }
 
 async fn demo_ws_kucoin_pu() {
-    // let mut bool_v1 = Arc::new(AtomicBool::new(true));
+    // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
     // let btree_map: BTreeMap<String, String> = BTreeMap::new();
     // let (tx, mut rx) = channel(1024);
     // let mut ku_ws = KucoinSwapWs::new(false, btree_map, KucoinWsType::Public, tx).await;
@@ -317,7 +317,7 @@ async fn demo_ws_kucoin_pu() {
     // ]);
     //
     // let t1 = tokio::spawn(async move {
-    //     ku_ws.custom_subscribe(bool_v1, vec!["ACHUSDTM".to_string(), "ROSEUSDTM".to_string()]).await;
+    //     ku_ws.custom_subscribe(is_shutdown_arc, vec!["ACHUSDTM".to_string(), "ROSEUSDTM".to_string()]).await;
     // });
     // let t2 = tokio::spawn(async move {
     //     loop {
@@ -478,7 +478,7 @@ async fn demo_rest_ba() {
 }
 
 async fn demo_pub_ws_ba() {
-    // let mut bool_v1 = Arc::new(AtomicBool::new(true));
+    // let mut is_shutdown_arc = Arc::new(AtomicBool::new(true));
     // let btree_map: BTreeMap<String, String> = BTreeMap::new();
     // let (tx, mut rx) = channel(1024);
     // let mut binance_ws = BinanceSwapWs::new(false, btree_map, BinanceWsType::PublicAndPrivate, tx);
@@ -488,7 +488,7 @@ async fn demo_pub_ws_ba() {
     //     BinanceSubscribeType::PuBookTicker,
     // ]);
     // let t1 = tokio::spawn(async move {
-    //     binance_ws.custom_subscribe(bool_v1,vec!["BTCUSDT".to_string()]).await;
+    //     binance_ws.custom_subscribe(is_shutdown_arc,vec!["BTCUSDT".to_string()]).await;
     // });
     // let t2 = tokio::spawn(async move {
     //     loop {

+ 14 - 14
standard/tests/exchange_test.rs

@@ -121,7 +121,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
             // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
             // let write_tx_am = Arc::new(Mutex::new(write_tx));
-            // let bool_v1 = Arc::new(AtomicBool::new(true));
+            // let is_shutdown_arc = Arc::new(AtomicBool::new(true));
             //
             // let params = BinanceSpotLogin {
             //     api_key: account_info.binance_access_key,
@@ -164,7 +164,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             //
             // let t1 = tokio::spawn(async move {
             //     //链接
-            //     let bool_v3_clone = Arc::clone(&bool_v1);
+            //     let bool_v3_clone = Arc::clone(&is_shutdown_arc);
             //     exchange_wss.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
             // });
             // try_join!(t1).unwrap();
@@ -176,7 +176,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
             // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
             // let write_tx_am = Arc::new(Mutex::new(write_tx));
-            // let bool_v1 = Arc::new(AtomicBool::new(true));
+            // let is_shutdown_arc = Arc::new(AtomicBool::new(true));
             //
             // let params = BinanceSwapLogin {
             //     api_key: account_info.binance_access_key,
@@ -219,7 +219,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             //
             // let t1 = tokio::spawn(async move {
             //     //链接
-            //     let bool_v3_clone = Arc::clone(&bool_v1);
+            //     let bool_v3_clone = Arc::clone(&is_shutdown_arc);
             //     exchange_wss.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
             // });
             // try_join!(t1).unwrap();
@@ -232,7 +232,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
             // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
             // let write_tx_am = Arc::new(Mutex::new(write_tx));
-            // let bool_v1 = Arc::new(AtomicBool::new(true));
+            // let is_shutdown_arc = Arc::new(AtomicBool::new(true));
             //
             // let params = KucoinSwapLogin {
             //     access_key: account_info.kucoin_access_key,
@@ -286,7 +286,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             //
             // let t1 = tokio::spawn(async move {
             //     //链接
-            //     let bool_v3_clone = Arc::clone(&bool_v1);
+            //     let bool_v3_clone = Arc::clone(&is_shutdown_arc);
             //     exchange_wss.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
             // });
             // try_join!(t1).unwrap();
@@ -299,7 +299,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
             // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
             // let write_tx_am = Arc::new(Mutex::new(write_tx));
-            // let bool_v1 = Arc::new(AtomicBool::new(true));
+            // let is_shutdown_arc = Arc::new(AtomicBool::new(true));
             //
             // let params = KucoinSpotLogin {
             //     access_key: account_info.kucoin_access_key,
@@ -355,7 +355,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // });
             // let t1 = tokio::spawn(async move {
             //     //链接
-            //     let bool_v3_clone = Arc::clone(&bool_v1);
+            //     let bool_v3_clone = Arc::clone(&is_shutdown_arc);
             //     exchange_wss.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
             // });
             // try_join!(t1).unwrap();
@@ -367,7 +367,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
             // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
             // let write_tx_am = Arc::new(Mutex::new(write_tx));
-            // let bool_v1 = Arc::new(AtomicBool::new(true));
+            // let is_shutdown_arc = Arc::new(AtomicBool::new(true));
             //
             // let params = GateSwapLogin {
             //     api_key: account_info.gate_access_key,
@@ -418,7 +418,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // });
             // let t1 = tokio::spawn(async move {
             //     //链接
-            //     let bool_v3_clone = Arc::clone(&bool_v1);
+            //     let bool_v3_clone = Arc::clone(&is_shutdown_arc);
             //     exchange_wss.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
             // });
             // try_join!(t1).unwrap();
@@ -431,7 +431,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
             // let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
             // let write_tx_am = Arc::new(Mutex::new(write_tx));
-            // let bool_v1 = Arc::new(AtomicBool::new(true));
+            // let is_shutdown_arc = Arc::new(AtomicBool::new(true));
             //
             // let params = BitgetSpotLogin {
             //     api_key: account_info.bitget_access_key,
@@ -489,7 +489,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             // });
             // let t1 = tokio::spawn(async move {
             //     //链接
-            //     let bool_v3_clone = Arc::clone(&bool_v1);
+            //     let bool_v3_clone = Arc::clone(&is_shutdown_arc);
             //     exchange_wss.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
             // });
             // try_join!(t1).unwrap();
@@ -501,7 +501,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
             let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
             let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded::<ResponseData>();
             let write_tx_am = Arc::new(Mutex::new(write_tx));
-            let bool_v1 = Arc::new(AtomicBool::new(true));
+            let is_shutdown_arc = Arc::new(AtomicBool::new(true));
 
             let params = OkxSwapLogin {
                 api_key: account_info.okx_access_key,
@@ -568,7 +568,7 @@ pub async fn test_new_exchange_wss<T>(exchange: ExchangeEnum, symbol: &str, subs
 
             let t1 = tokio::spawn(async move {
                 //链接
-                let bool_v3_clone = Arc::clone(&bool_v1);
+                let bool_v3_clone = Arc::clone(&is_shutdown_arc);
                 exchange_wss.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
             });
             try_join!(t1).unwrap();

+ 3 - 3
strategy/src/binance_spot.rs

@@ -13,7 +13,7 @@
 // use crate::core::Core;
 //
 // // 参考 币安 现货 启动
-// pub async fn reference_binance_spot_run(bool_v1 :Arc<AtomicBool>,
+// pub async fn reference_binance_spot_run(is_shutdown_arc :Arc<AtomicBool>,
 //                                         core_arc: Arc<Mutex<Core>>,
 //                                         name: String,
 //                                         symbols: Vec<String>,
@@ -35,7 +35,7 @@
 //
 //     spawn(async move {
 //         //链接
-//         let bool_v3_clone = Arc::clone(&bool_v1);
+//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
 //         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
 //     });
 //
@@ -65,7 +65,7 @@
 //     //         // BinanceSpotSubscribeType::PuBookTicker,
 //     //         BinanceSpotSubscribeType::PuDepth20levels100ms
 //     //     ]);
-//     //     ba_exc.custom_subscribe(bool_v1, symbols.clone()).await;
+//     //     ba_exc.custom_subscribe(is_shutdown_arc, symbols.clone()).await;
 //     // });
 //     //
 //     // spawn(async move {

+ 60 - 74
strategy/src/binance_usdt_swap.rs

@@ -1,20 +1,19 @@
 use std::collections::BTreeMap;
 use std::sync::Arc;
 use std::sync::atomic::AtomicBool;
-use futures_util::StreamExt;
-use rust_decimal::Decimal;
+// use rust_decimal::Decimal;
 use tokio::sync::Mutex;
-use exchanges::response_base::ResponseData;
-use global::trace_stack::TraceStack;
-use standard::exchange::ExchangeEnum::BinanceSwap;
+// use exchanges::response_base::ResponseData;
+// use global::trace_stack::TraceStack;
+// use standard::exchange::ExchangeEnum::BinanceSwap;
 // use crate::model::{OriginalTradeBa};
 use crate::core::Core;
 use exchanges::binance_swap_ws::{BinanceSwapSubscribeType, BinanceSwapWs, BinanceSwapWsType};
-use crate::exchange_disguise::{on_special_depth};
+// use crate::exchange_disguise::{on_special_depth};
 
 // 参考 币安 合约 启动
-pub(crate) async fn reference_binance_swap_run(bool_v1 :Arc<AtomicBool>,
-                                               core_arc: Arc<Mutex<Core>>,
+pub(crate) async fn reference_binance_swap_run(is_shutdown_arc :Arc<AtomicBool>,
+                                               _core_arc: Arc<Mutex<Core>>,
                                                name: String,
                                                symbols: Vec<String>,
                                                is_colo: bool,
@@ -22,7 +21,6 @@ pub(crate) async fn reference_binance_swap_run(bool_v1 :Arc<AtomicBool>,
     tokio::spawn(async move {
         //创建读写通道
         let (write_tx, write_rx) = futures_channel::mpsc::unbounded();
-        let (read_tx, mut read_rx) = futures_channel::mpsc::unbounded();
         let mut ws = BinanceSwapWs::new_label(name, is_colo, None, BinanceSwapWsType::PublicAndPrivate);
         ws.set_symbols(symbols);
         ws.set_subscribe(vec![
@@ -32,74 +30,62 @@ pub(crate) async fn reference_binance_swap_run(bool_v1 :Arc<AtomicBool>,
         ]);
 
         //读取数据
-        let core_arc_clone = Arc::clone(&core_arc);
-        tokio::spawn(async move {
-            // ticker
-            let mut update_flag_u = Decimal::ZERO;
-
-            loop {
-                while let Some(data) = read_rx.next().await {
-                    on_data(core_arc_clone.clone(),
-                            &mut update_flag_u,
-                            data).await;
-                }
-            }
-        });
+        // let core_arc_clone = Arc::clone(&core_arc);
 
         // 链接
         let write_tx_am = Arc::new(Mutex::new(write_tx));
-        ws.ws_connect_async(bool_v1, &write_tx_am, write_rx, read_tx).await.expect("链接失败");
+        ws.ws_connect_async(is_shutdown_arc, &write_tx_am, write_rx).await.expect("链接失败");
     });
 }
 
-async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
-                 update_flag_u: &mut Decimal,
-                 data: ResponseData) {
-    let mut trace_stack = TraceStack::default();
-    trace_stack.on_after_network(data.time);
-    trace_stack.on_before_unlock_core();
-
-    if data.code != "200".to_string() {
-        return;
-    }
-
-    if data.channel == "aggTrade" {
-        // let trade: OriginalTradeBa = serde_json::from_str(data.data.as_str()).unwrap();
-        // let name = data.label.clone();
-
-        // 订单流逻辑
-        // on_trade(trade.clone(), core_arc_clone.clone()).await;
-
-        // 原本的逻辑
-        // let mut core = core_arc_clone.lock().await;
-        // let str = data.label.clone();
-        // if core.is_update.contains_key(&data.label) && *core.is_update.get(str.as_str()).unwrap() {
-        //     *_max_buy = Decimal::ZERO;
-        //     *_min_sell = Decimal::ZERO;
-        //     core.is_update.remove(str.as_str());
-        // }
-        // if trade.p > *_max_buy || *_max_buy == Decimal::ZERO {
-        //     *_max_buy = trade.p
-        // }
-        // if trade.p < *_min_sell || *_min_sell == Decimal::ZERO {
-        //     *_min_sell = trade.p
-        // }
-        // core.max_buy_min_sell_cache.insert(data.label, vec![*_max_buy, *_min_sell]);
-    } else if data.channel == "bookTicker" {
-        trace_stack.on_before_format();
-        // 将ticker数据转换为模拟深度
-        let special_depth = standard::handle_info::HandleSwapInfo::handle_special_ticker(BinanceSwap, data.clone());
-        trace_stack.on_before_network(special_depth.create_at.clone());
-        trace_stack.on_after_format();
-
-        on_special_depth(core_arc_clone, update_flag_u, data.label.clone(), trace_stack, special_depth).await;
-    } else if data.channel == "depth" {
-        trace_stack.on_before_format();
-        // 将depth数据转换为模拟深度
-        let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(BinanceSwap, data.clone());
-        trace_stack.on_before_network(special_depth.create_at.clone());
-        trace_stack.on_after_format();
-
-        on_special_depth(core_arc_clone, update_flag_u, data.label.clone(), trace_stack, special_depth).await;
-    }
-}
+// async fn on_data(core_arc_clone: Arc<Mutex<Core>>,
+//                  update_flag_u: &mut Decimal,
+//                  data: ResponseData) {
+//     let mut trace_stack = TraceStack::default();
+//     trace_stack.on_after_network(data.time);
+//     trace_stack.on_before_unlock_core();
+//
+//     if data.code != "200".to_string() {
+//         return;
+//     }
+//
+//     if data.channel == "aggTrade" {
+//         // let trade: OriginalTradeBa = serde_json::from_str(data.data.as_str()).unwrap();
+//         // let name = data.label.clone();
+//
+//         // 订单流逻辑
+//         // on_trade(trade.clone(), core_arc_clone.clone()).await;
+//
+//         // 原本的逻辑
+//         // let mut core = core_arc_clone.lock().await;
+//         // let str = data.label.clone();
+//         // if core.is_update.contains_key(&data.label) && *core.is_update.get(str.as_str()).unwrap() {
+//         //     *_max_buy = Decimal::ZERO;
+//         //     *_min_sell = Decimal::ZERO;
+//         //     core.is_update.remove(str.as_str());
+//         // }
+//         // if trade.p > *_max_buy || *_max_buy == Decimal::ZERO {
+//         //     *_max_buy = trade.p
+//         // }
+//         // if trade.p < *_min_sell || *_min_sell == Decimal::ZERO {
+//         //     *_min_sell = trade.p
+//         // }
+//         // core.max_buy_min_sell_cache.insert(data.label, vec![*_max_buy, *_min_sell]);
+//     } else if data.channel == "bookTicker" {
+//         trace_stack.on_before_format();
+//         // 将ticker数据转换为模拟深度
+//         let special_depth = standard::handle_info::HandleSwapInfo::handle_special_ticker(BinanceSwap, data.clone());
+//         trace_stack.on_before_network(special_depth.create_at.clone());
+//         trace_stack.on_after_format();
+//
+//         on_special_depth(core_arc_clone, update_flag_u, data.label.clone(), trace_stack, special_depth).await;
+//     } else if data.channel == "depth" {
+//         trace_stack.on_before_format();
+//         // 将depth数据转换为模拟深度
+//         let special_depth = standard::handle_info::HandleSwapInfo::handle_special_depth(BinanceSwap, data.clone());
+//         trace_stack.on_before_network(special_depth.create_at.clone());
+//         trace_stack.on_after_format();
+//
+//         on_special_depth(core_arc_clone, update_flag_u, data.label.clone(), trace_stack, special_depth).await;
+//     }
+// }

+ 5 - 5
strategy/src/bitget_spot.rs

@@ -15,7 +15,7 @@
 // use crate::model::{OrderInfo, OriginalTradeGa};
 // use crate::core::Core;
 //
-// pub async fn bitget_spot_run(bool_v1 :Arc<AtomicBool>,
+// pub async fn bitget_spot_run(is_shutdown_arc :Arc<AtomicBool>,
 //                              is_trade: bool,
 //                              core_arc: Arc<Mutex<Core>>,
 //                              name: String,
@@ -43,10 +43,10 @@
 //         ]);
 //     }
 //     // 开启公共连接
-//     let bool_v1_c1 = bool_v1.clone();
+//     let is_shutdown_arc_c1 = is_shutdown_arc.clone();
 //     let write_tx_am_public = Arc::new(Mutex::new(write_tx_public));
 //     spawn(async move {
-//         ku_public.ws_connect_async(bool_v1_c1,
+//         ku_public.ws_connect_async(is_shutdown_arc_c1,
 //                                    &write_tx_am_public,
 //                                    write_rx_public,
 //                                    read_tx_public)
@@ -90,7 +90,7 @@
 //         // 其余也要再开两个通道,不能与公共频道混用
 //         let (write_tx_private, write_rx_public) = futures_channel::mpsc::unbounded();
 //         let (read_tx_private, mut read_rx_public) = futures_channel::mpsc::unbounded();
-//         let bool_v1_c2 = bool_v1.clone();
+//         let is_shutdown_arc_c2 = is_shutdown_arc.clone();
 //         let write_tx_am_private = Arc::new(Mutex::new(write_tx_private));
 //         spawn(async move {
 //             let login_params = parse_btree_map_to_bitget_spot_login(exchange_params);
@@ -104,7 +104,7 @@
 //                 BitgetSpotSubscribeType::PrOrders,
 //             ]);
 //
-//             ku_private.ws_connect_async(bool_v1_c2,
+//             ku_private.ws_connect_async(is_shutdown_arc_c2,
 //                                         &write_tx_am_private,
 //                                         write_rx_public,
 //                                         read_tx_private)

+ 3 - 3
strategy/src/bybit_usdt_swap.rs

@@ -18,7 +18,7 @@
 // use crate::exchange_disguise::on_special_depth;
 //
 // // 1交易、0参考 bybit 合约 启动
-// pub async fn bybit_swap_run(bool_v1: Arc<AtomicBool>,
+// pub async fn bybit_swap_run(is_shutdown_arc: Arc<AtomicBool>,
 //                            is_trade: bool,
 //                            _core_arc: Arc<Mutex<Core>>,
 //                            name: String,
@@ -41,7 +41,7 @@
 //     }
 //     // 挂起公共ws
 //     let write_tx_am_public = Arc::new(Mutex::new(write_tx_public));
-//     let bool_clone_public = Arc::clone(&bool_v1);
+//     let bool_clone_public = Arc::clone(&is_shutdown_arc);
 //      spawn(async move {
 //         ws_public.ws_connect_async(bool_clone_public,
 //                                    &write_tx_am_public,
@@ -89,7 +89,7 @@
 //
 //         // 挂起私有ws
 //         let write_tx_am_private = Arc::new(Mutex::new(write_tx_private));
-//         let bool_clone_private = Arc::clone(&bool_v1);
+//         let bool_clone_private = Arc::clone(&is_shutdown_arc);
 //         spawn(async move {
 //             ws_private.ws_connect_async(bool_clone_private,
 //                                         &write_tx_am_private,

+ 15 - 15
strategy/src/exchange_disguise.rs

@@ -17,7 +17,7 @@ use crate::binance_usdt_swap::reference_binance_swap_run;
 use crate::core::Core;
 
 // 交易交易所启动
-// pub async fn run_transactional_exchange(bool_v1 :Arc<AtomicBool>,
+// pub async fn run_transactional_exchange(is_shutdown_arc :Arc<AtomicBool>,
 //                                         exchange_name: String,
 //                                         core_arc: Arc<Mutex<Core>>,
 //                                         name: String,
@@ -26,19 +26,19 @@ use crate::core::Core;
 //                                         exchange_params: BTreeMap<String, String>) {
 //     match exchange_name.as_str() {
 //         "gate_usdt_swap" => {
-//             gate_swap_run(bool_v1, true, core_arc, name, symbols, is_colo, exchange_params).await;
+//             gate_swap_run(is_shutdown_arc, true, core_arc, name, symbols, is_colo, exchange_params).await;
 //         }
 //         // "kucoin_usdt_swap" => {
-//         //     kucoin_swap_run(bool_v1, true, core_arc, name, symbols, is_colo, exchange_params).await;
+//         //     kucoin_swap_run(is_shutdown_arc, true, core_arc, name, symbols, is_colo, exchange_params).await;
 //         // },
 //         // "okex_usdt_swap" => {
-//         //     okex_swap_run(bool_v1,true, core_arc, name, symbols, is_colo, exchange_params).await;
+//         //     okex_swap_run(is_shutdown_arc,true, core_arc, name, symbols, is_colo, exchange_params).await;
 //         // },
 //         // "bitget_spot" => {
-//         //     bitget_spot_run(bool_v1,true, core_arc, name, symbols, is_colo, exchange_params).await;
+//         //     bitget_spot_run(is_shutdown_arc,true, core_arc, name, symbols, is_colo, exchange_params).await;
 //         // },
 //         // "bybit_usdt_swap" => {
-//         //     bybit_swap_run(bool_v1,true, core_arc, name, symbols, is_colo, exchange_params).await;
+//         //     bybit_swap_run(is_shutdown_arc,true, core_arc, name, symbols, is_colo, exchange_params).await;
 //         // }
 //         _ => {
 //             let msg = format!("不支持的交易交易所:{}", exchange_name);
@@ -48,7 +48,7 @@ use crate::core::Core;
 // }
 
 // 参考交易所启动
-pub async fn run_reference_exchange(bool_v1: Arc<AtomicBool>,
+pub async fn run_reference_exchange(is_shutdown_arc: Arc<AtomicBool>,
                                     exchange_name: String,
                                     core_arc: Arc<Mutex<Core>>,
                                     name: String,
@@ -57,28 +57,28 @@ pub async fn run_reference_exchange(bool_v1: Arc<AtomicBool>,
                                     exchange_params: BTreeMap<String, String>) {
     match exchange_name.as_str() {
         "binance_usdt_swap" => {
-            reference_binance_swap_run(bool_v1, core_arc, name, symbols, is_colo, exchange_params).await;
+            reference_binance_swap_run(is_shutdown_arc, core_arc, name, symbols, is_colo, exchange_params).await;
         },
         // "binance_spot" => {
-        //     reference_binance_spot_run(bool_v1, core_arc, name, symbols, is_colo, exchange_params).await;
+        //     reference_binance_spot_run(is_shutdown_arc, core_arc, name, symbols, is_colo, exchange_params).await;
         // },
         // "gate_usdt_swap" => {
-        //     gate_swap_run(bool_v1, false, core_arc, name, symbols, is_colo, exchange_params).await;
+        //     gate_swap_run(is_shutdown_arc, false, core_arc, name, symbols, is_colo, exchange_params).await;
         // },
         // "okex_usdt_swap" => {
-        //     okex_swap_run(bool_v1, false, core_arc, name, symbols, is_colo, exchange_params).await;
+        //     okex_swap_run(is_shutdown_arc, false, core_arc, name, symbols, is_colo, exchange_params).await;
         // },
         // "kucoin_usdt_swap" => {
-        //     kucoin_swap_run(bool_v1, false, core_arc, name, symbols, is_colo, exchange_params).await;
+        //     kucoin_swap_run(is_shutdown_arc, false, core_arc, name, symbols, is_colo, exchange_params).await;
         // },
         // "kucoin_spot" => {
-        //     kucoin_spot_run(bool_v1, false, core_arc, name, symbols, is_colo, exchange_params).await;
+        //     kucoin_spot_run(is_shutdown_arc, false, core_arc, name, symbols, is_colo, exchange_params).await;
         // },
         // "bitget_spot" => {
-        //     bitget_spot_run(bool_v1, false, core_arc, name, symbols, is_colo, exchange_params).await;
+        //     bitget_spot_run(is_shutdown_arc, false, core_arc, name, symbols, is_colo, exchange_params).await;
         // },
         // "bybit_usdt_swap" => {
-        //     bybit_swap_run(bool_v1, false, core_arc, name, symbols, is_colo, exchange_params).await;
+        //     bybit_swap_run(is_shutdown_arc, false, core_arc, name, symbols, is_colo, exchange_params).await;
         // },
         _ => {
             let msg = format!("不支持的参考交易所:{}", exchange_name);

+ 2 - 2
strategy/src/gate_swap.rs

@@ -17,7 +17,7 @@
 // use crate::exchange_disguise::on_special_depth;
 //
 // // 1交易、0参考 gate 合约 启动
-// pub async fn gate_swap_run(bool_v1: Arc<AtomicBool>,
+// pub async fn gate_swap_run(is_shutdown_arc: Arc<AtomicBool>,
 //                            is_trade: bool,
 //                            core_arc: Arc<Mutex<Core>>,
 //                            name: String,
@@ -67,7 +67,7 @@
 //         }
 //
 //         ws.set_symbols(symbols_clone);
-//         ws.ws_connect_async(bool_v1, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
+//         ws.ws_connect_async(is_shutdown_arc, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
 //     });
 //
 //     spawn(async move {

+ 3 - 3
strategy/src/kucoin_spot.rs

@@ -13,7 +13,7 @@
 // use crate::core::Core;
 //
 // // 1交易、0参考 kucoin 现货 启动
-// pub async fn kucoin_spot_run(bool_v1: Arc<AtomicBool>,
+// pub async fn kucoin_spot_run(is_shutdown_arc: Arc<AtomicBool>,
 //                              _is_trade: bool,
 //                              core_arc: Arc<Mutex<Core>>,
 //                              name: String,
@@ -42,11 +42,11 @@
 //     let write_tx_am = Arc::new(Mutex::new(write_tx));
 //     tokio::spawn(async move {
 //         //链接
-//         let bool_v3_clone = Arc::clone(&bool_v1);
+//         let bool_v3_clone = Arc::clone(&is_shutdown_arc);
 //         ws.ws_connect_async(bool_v3_clone, &write_tx_am, write_rx, read_tx).await.expect("链接失败(内部一个心跳线程应该已经关闭了)");
 //     });
 //     //读取
-//     // let bool_v1_clone = Arc::clone(&bool_v1);
+//     // let is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
 //     tokio::spawn(async move {
 //         let core_arc_clone = Arc::clone(&core_arc);
 //         // trade

+ 3 - 3
strategy/src/kucoin_swap.rs

@@ -20,7 +20,7 @@
 // use crate::core::Core;
 //
 // // 1交易、0参考 kucoin 合约 启动
-// pub async fn kucoin_swap_run(bool_v1 :Arc<AtomicBool>,
+// pub async fn kucoin_swap_run(is_shutdown_arc :Arc<AtomicBool>,
 //                              is_trade: bool,
 //                              core_arc: Arc<Mutex<Core>>,
 //                              name: String,
@@ -57,7 +57,7 @@
 //         spawn( async move {
 //             let mut kucoin_exc;
 //             //模拟业务场景 开启链接
-//             let bool_v1_clone = Arc::clone(&bool_v1);
+//             let is_shutdown_arc_clone = Arc::clone(&is_shutdown_arc);
 //             let write_tx_am = Arc::new(Mutex::new(write_tx));
 //
 //             // 交易
@@ -82,7 +82,7 @@
 //             }
 //
 //             kucoin_exc.set_symbols(symbol_arr);
-//             kucoin_exc.ws_connect_async(bool_v1_clone, &write_tx_am, write_rx, read_tx).await.unwrap();
+//             kucoin_exc.ws_connect_async(is_shutdown_arc_clone, &write_tx_am, write_rx, read_tx).await.unwrap();
 //         });
 //
 //         // 数据处理协程

+ 3 - 3
strategy/src/okx_usdt_swap.rs

@@ -12,7 +12,7 @@
 // use crate::model::{OrderInfo, OriginalTradeOK};
 // use crate::core::Core;
 //
-// pub async fn okex_swap_run(bool_v1: Arc<AtomicBool>,
+// pub async fn okex_swap_run(is_shutdown_arc: Arc<AtomicBool>,
 //                            is_trade: bool,
 //                            _core_arc: Arc<Mutex<Core>>,
 //                            name: String,
@@ -36,7 +36,7 @@
 //     }
 //     // 挂起公共ws
 //     let write_tx_am_public = Arc::new(Mutex::new(write_tx_public));
-//     let bool_clone_public = Arc::clone(&bool_v1);
+//     let bool_clone_public = Arc::clone(&is_shutdown_arc);
 //     tokio::spawn(async move {
 //         ws_public.ws_connect_async(bool_clone_public,
 //                                    &write_tx_am_public,
@@ -80,7 +80,7 @@
 //
 //         // 挂起私有ws
 //         let write_tx_am_private = Arc::new(Mutex::new(write_tx_private));
-//         let bool_clone_private = Arc::clone(&bool_v1);
+//         let bool_clone_private = Arc::clone(&is_shutdown_arc);
 //         tokio::spawn(async move {
 //             ws_private.ws_connect_async(bool_clone_private,
 //                                 &write_tx_am_private,