Browse Source

Merge remote-tracking branch 'origin/master'

skyfffire 2 years ago
parent
commit
48dbab4d83

+ 4 - 0
exchanges/Cargo.toml

@@ -19,3 +19,7 @@ reqwest = { version = "0.11.14", features = ["json"] }
 
 ring = "0.16.20"
 data-encoding = "2.4.0"
+
+
+hmac = "0.8.1"
+sha2 = "0.9.8"

+ 1 - 1
exchanges/src/binance_usdt_swap_rest.rs

@@ -46,7 +46,7 @@ impl BinanceUsdtSwapRest {
 
         //组装登陆认证信息
         let params = self.get_sign(btree_map);
-        let mut get_response = self.rest.http_toll(
+        let  get_response = self.rest.http_toll(
             "/fapi/v2/balance".to_string(),
             "get".to_string(),
             params,

+ 7 - 14
exchanges/src/binance_usdt_swap_ws.rs

@@ -1,20 +1,16 @@
 use std::collections::BTreeMap;
 use std::future::Future;
-use std::{io, thread};
-use std::io::{Read, Write};
+use std::{io};
+use std::io::{Write};
 use std::net::{IpAddr, Ipv4Addr, SocketAddr};
 use std::sync::Arc;
-use std::time::Duration;
-use chrono::Utc;
 use serde_json::json;
 use tokio::sync::Mutex;
 use crate::proxy;
 use crate::response_base::ResponseData;
 use tungstenite::client::{AutoStream, connect_with_proxy, ProxyAutoStream};
 use tungstenite::{connect, Message, WebSocket};
-use tungstenite::http::Response;
 use tungstenite::protocol::WebSocketConfig;
-use tungstenite::stream::Stream;
 use url::Url;
 
 
@@ -49,7 +45,6 @@ impl BinanceUsdtSwapWs {
         }
         let mut ip_v = "";
         let mut port_v = 8080;
-        let mut v_str = String::from("");
 
         /*******走代理:根据环境变量配置来决定,如果配置了走代理,没有配置不走*******/
         let parsing_detail = proxy::ParsingDetail::parsing_environment_variables();
@@ -114,7 +109,6 @@ impl BinanceUsdtSwapWs {
     /*****************************************工具函数********************************************************/
     /*******************************************************************************************************/
     fn log_in_to_str(&self) -> String {
-        let login_param = self.login_param.clone();
         let mut login_json_str = String::from("");
 
         //
@@ -183,8 +177,7 @@ impl BinanceUsdtSwapWs {
         let parse_fn_arc = Arc::new(Mutex::new(parse_fn)); // Wrap the closure in an Arc<Mutex<_>>
         loop {
             //币安-登陆流程-rest请求获取k然后拿到 key 拼接地址
-            if self.is_login{ //暂时没看到有订阅的频道需要登陆 所以暂时不做
-
+            if self.is_login { //暂时没看到有订阅的频道需要登陆 所以暂时不做
             }
 
             let request_url = Url::parse(self.request_url.as_str()).unwrap();
@@ -231,7 +224,7 @@ impl BinanceUsdtSwapWs {
     {
         /*****消息溜***/
         let mut stdout = io::stdout();
-        let mut stderr = io::stderr();
+        // let mut stderr = io::stderr();
         // /*****是否需要登陆****/
         // if self.is_login {
         //     println!("----需要登陆");
@@ -286,7 +279,7 @@ impl BinanceUsdtSwapWs {
     {
         /*****消息溜***/
         let mut stdout = io::stdout();
-        let mut stderr = io::stderr();
+        // let mut stderr = io::stderr();
         /*****是否需要登陆****/
         // if self.is_login {
         //     println!("----需要登陆");
@@ -343,9 +336,9 @@ impl BinanceUsdtSwapWs {
         } else {
             //数据解析
             if json_value.get("e").is_some() {
-               let e =  json_value["e"].as_str().unwrap_or("----");
+                let e = json_value["e"].as_str().unwrap_or("----");
                 res_data.channel = e.to_string();
-            }else{
+            } else {
                 res_data.channel = "bookTicker".to_string()
             }
             res_data.data = text

+ 208 - 0
exchanges/src/gate_swap_rest.rs

@@ -0,0 +1,208 @@
+use std::collections::BTreeMap;
+use reqwest::header::HeaderMap;
+use ring::{digest};
+use hex;
+use hmac::{Hmac, Mac, NewMac};
+use crate::http_tool::RestTool;
+use crate::response_base::ResponseData;
+use sha2::Sha512;
+
+pub struct GateSwapRest {
+    /*******参数*/
+    //是否需要登陆
+    is_login: bool,
+    //登陆所需参数
+    login_param: BTreeMap<String, String>,
+    rest: RestTool,
+}
+
+impl GateSwapRest {
+    /*******************************************************************************************************/
+    /*****************************************获取一个对象****************************************************/
+    /*******************************************************************************************************/
+    pub fn new(is_colo: bool, is_login: bool, login_param: BTreeMap<String, String>) -> GateSwapRest
+    {
+        let mut base_url = String::from("");
+        if is_colo {
+            println!("使用colo高速线路");
+            base_url = "https://apiv4-private.gateapi.io".to_string()
+        } else {
+            base_url = "https://api.gateio.ws".to_string()
+        }
+
+        /*****返回结构体*******/
+        GateSwapRest {
+            is_login,
+            login_param,
+            rest: RestTool::new(base_url.to_string()),
+        }
+    }
+
+    /*******************************************************************************************************/
+    /*****************************************rest请求函数********************************************************/
+    /*******************************************************************************************************/
+    pub async fn get_server_time(&self) -> ResponseData {
+        let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
+        let data = self.request("GET".to_string(),
+                                "/api/v4".to_string(),
+                                format!("/spot/time"),
+                                true,
+                                btree_map,
+        ).await;
+        data
+    }
+    pub async fn get_account(&self, settle: String) -> ResponseData {
+        let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
+        let data = self.request("GET".to_string(),
+                                "/api/v4".to_string(),
+                                format!("/futures/{}/accounts", settle),
+                                true,
+                                btree_map,
+        ).await;
+        data
+    }
+    pub async fn get_position(&self, settle: String, contract: String) -> ResponseData {
+        let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
+        let data = self.request("GET".to_string(),
+                                "/api/v4".to_string(),
+                                format!("/futures/{}/dual_comp/positions/{}", settle, contract),
+                                true,
+                                btree_map,
+        ).await;
+        data
+    }
+    pub async fn get_ticker(&self, settle: String) -> ResponseData {
+        let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
+        let data = self.request("GET".to_string(),
+                                "/api/v4".to_string(),
+                                format!("/futures/{}/tickers", settle),
+                                true,
+                                btree_map,
+        ).await;
+        data
+    }
+    pub async fn get_market_details(&self, settle: String) -> ResponseData {
+        let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
+        let data = self.request("GET".to_string(),
+                                "/api/v4".to_string(),
+                                format!("/futures/{}/contracts", settle),
+                                true,
+                                btree_map,
+        ).await;
+        data
+    }
+
+
+    /*******************************************************************************************************/
+    /*****************************************工具函数********************************************************/
+    /*******************************************************************************************************/
+    //调用请求
+    async fn request(&self,
+                     requesst_type: String,
+                     prefix_url: String,
+                     request_url: String,
+                     is_login: bool,
+                     params: BTreeMap<String, String>) -> ResponseData
+    {
+        // println!("login_param:{:?}", self.login_param);
+        //解析账号信息
+        let mut access_key = "".to_string();
+        let mut secret_key = "".to_string();
+        if self.login_param.contains_key("access_key") {
+            access_key = self.login_param.get("access_key").unwrap().to_string();
+        }
+        if self.login_param.contains_key("secret_key") {
+            secret_key = self.login_param.get("secret_key").unwrap().to_string();
+        }
+        let mut is_login_param = true;
+        if access_key == "" || secret_key == "" {
+            is_login_param = false
+        }
+
+        //请求头配置-如果需要登陆则存在额外配置
+        let mut body = "".to_string();
+        let mut sing = "".to_string();
+        let timestamp = chrono::Utc::now().timestamp().to_string();
+
+        let mut headers = HeaderMap::new();
+        if requesst_type == "GET" {
+            headers.insert("Content-type", "application/x-www-form-urlencoded".parse().unwrap());
+            headers.insert("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ".parse().unwrap());
+        } else {
+            headers.insert("Accept", "application/json".parse().unwrap());
+            headers.insert("Content-Type", "application/json".parse().unwrap());
+        }
+
+        //是否需要登陆-- 组装sing
+        if is_login {
+            if !is_login_param {
+                let e = ResponseData::error("登陆参数错误!".to_string());
+                return e;
+            } else {//需要登陆-且登陆参数齐全
+                //组装sing
+                sing = Self::sign(secret_key.clone(),
+                                  requesst_type.clone(),
+                                  prefix_url.clone(),
+                                  request_url.clone(),
+                                  params.clone(),
+                                  body.clone(),
+                                  timestamp.clone(),
+                );
+                // println!("sing:{}", sing);
+                //组装header
+                headers.extend(Self::headers(access_key, timestamp, sing));
+            }
+        }
+
+        // println!("headers:{:?}", headers);
+        let mut get_response = self.rest.http_toll(
+            format!("{}{}", prefix_url.clone(), request_url.clone()),
+            requesst_type.to_string(),
+            params,
+            headers,
+        ).await;
+        let mut req_data = RestTool::req_data_analysis(get_response);
+        req_data
+    }
+
+    pub fn headers(access_key: String, timestamp: String, sign: String) -> HeaderMap {
+        let mut headers = HeaderMap::new();
+        headers.insert("KEY", access_key.clone().parse().unwrap());
+        headers.insert("Timestamp", timestamp.clone().parse().unwrap());
+        headers.insert("SIGN", sign.clone().parse().unwrap());
+        headers
+    }
+    pub fn sign(secret_key: String,
+                requesst_type: String, prefix_url: String, request_url: String,
+                params: BTreeMap<String, String>, body_data: String, timestamp: String) -> String
+    {
+        let url = format!("{}{}", prefix_url, request_url);
+        let t = chrono::Utc::now().timestamp().to_string();
+        let params_str = RestTool::parse_params_to_str(params.clone());
+        let body = Some(body_data);
+        let hashed_payload = if let Some(body) = body {
+            let mut m = digest::Context::new(&digest::SHA512);
+            m.update(body.as_bytes());
+            hex::encode(m.finish().as_ref())
+        } else {
+            String::new()
+        };
+        // println!("hashed_payload:{}", hashed_payload);
+
+        let message = format!("{}\n{}\n{}\n{}\n{}",
+                              requesst_type,
+                              url,
+                              params_str,
+                              hashed_payload,
+                              t);
+        // println!("**********", );
+        // println!("组装数据:{}", message);
+        // println!("**********", );
+
+        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
+    }
+}

+ 10 - 0
exchanges/src/gate_swap_ws.rs

@@ -0,0 +1,10 @@
+use std::collections::BTreeMap;
+
+pub struct GateSwapWs {}
+
+impl GateSwapWs {
+    pub fn new(is_colo: bool, is_login: bool, login_param: BTreeMap<String, String>) -> GateSwapWs
+    {
+        GateSwapWs {}
+    }
+}

+ 0 - 10
exchanges/src/gate_usdt_swap_rest.rs

@@ -1,10 +0,0 @@
-use std::collections::BTreeMap;
-
-pub struct GateUsdtSwapRest {}
-
-impl GateUsdtSwapRest {
-    pub fn new(is_colo: bool, is_login: bool, login_param: BTreeMap<String, String>) -> GateUsdtSwapRest
-    {
-        GateUsdtSwapRest {}
-    }
-}

+ 0 - 10
exchanges/src/gate_usdt_swap_ws.rs

@@ -1,10 +0,0 @@
-use std::collections::BTreeMap;
-
-pub struct GateUsdtSwapWs {}
-
-impl GateUsdtSwapWs {
-    pub fn new(is_colo: bool, is_login: bool, login_param: BTreeMap<String, String>) -> GateUsdtSwapWs
-    {
-        GateUsdtSwapWs {}
-    }
-}

+ 14 - 47
exchanges/src/http_tool.rs

@@ -1,21 +1,15 @@
-use std::collections::{BTreeMap, HashMap};
-use std::thread::sleep;
-use reqwest::{Client, RequestBuilder, Response};
+use std::collections::{BTreeMap};
+use reqwest::{Client};
 use reqwest::header::HeaderMap;
-use crate::proxy;
 use crate::response_base::ResponseData;
 
 pub struct RestTool {
-    base_url: String,
+    pub base_url: String,
     client: Client,
 }
 
 impl RestTool {
     pub fn new(base_url: String) -> RestTool {
-        /*******走代理:根据环境变量配置来决定,如果配置了走代理,没有配置不走*******/
-        if proxy::ParsingDetail::http_enable_proxy() {
-            println!("检测有代理配置,配置走代理")
-        }
         RestTool { base_url, client: Client::new() }
     }
     pub async fn demo() -> Result<(), reqwest::Error> {
@@ -32,23 +26,11 @@ impl RestTool {
         let req_data = RestTool::req_data_analysis(get_response);
         println!("GET Response: {:?}", req_data);
 
-        //
-        // // 发送POST请求
-        // let post_response = RestTool::send_post_request().await?;
-        // println!("POST Response: {:?}", post_response);
-        //
-        // // 发送DELETE请求
-        // let delete_response = RestTool::send_delete_request().await?;
-        // println!("DELETE Response: {:?}", delete_response);
-        //
-        // // 发送PUT请求
-        // let put_response = RestTool::send_put_request().await?;
-        // println!("PUT Response: {:?}", put_response);
 
         Ok(())
     }
-    pub async fn http_toll(&self, request_path: String, request_type: String, params: BTreeMap<String, String>, headers: HeaderMap) -> Result<(ResponseData), reqwest::Error> {
-        let mut req_data: ResponseData;
+    pub async fn http_toll(&self, request_path: String, request_type: String, params: BTreeMap<String, String>, headers: HeaderMap) -> Result<ResponseData, reqwest::Error> {
+        let  req_data: ResponseData;
         /****请求接口与 地址*/
         let url = format!("{}{}", self.base_url.to_string(), request_path);
         let request_type = request_type.clone().to_uppercase();
@@ -56,7 +38,7 @@ impl RestTool {
         println!("------{}", zzz_url);
 
 
-        let mut req = match request_type.as_str() {
+        let  req = match request_type.as_str() {
             "GET" => self.client.get(zzz_url.clone()).headers(headers),
             "POST" => self.client.post(url.clone()).headers(headers).json(&params),
             // "DELETE" => self.client.delete(url.clone()).json(&params),
@@ -68,18 +50,18 @@ impl RestTool {
         if response.status().is_success() {
             // 读取响应的内容
             let body = response.text().await?;
-            println!("ok-----{}",body);
+            println!("ok-----{}", body);
             req_data = ResponseData::new("200".to_string(), "success".to_string(), body);
         } else {
             let body = response.text().await?;
-            println!("error-----{}",body);
+            println!("error-----{}", body);
             req_data = ResponseData::error(body.to_string())
         }
         Ok(req_data)
     }
 
-    pub async fn get(&self, request_path: &str, params: BTreeMap<&str, &str>) -> Result<(ResponseData), reqwest::Error> {
-        let mut req_data: ResponseData;
+    pub async fn get(&self, request_path: &str, params: BTreeMap<&str, &str>) -> Result<ResponseData, reqwest::Error> {
+        let  req_data: ResponseData;
         /*请求接口与 地址*/
         let url = format!("{}{}", self.base_url.to_string(), request_path);
         let req = self.client
@@ -98,11 +80,11 @@ impl RestTool {
             let body = response.text().await?;
             req_data = ResponseData::error(body.to_string())
         }
-        Ok((req_data))
+        Ok(req_data)
     }
 
-    pub async fn post_v(&self, request_path: String, params: BTreeMap<&str, &str>) -> Result<(ResponseData), reqwest::Error> {
-        let mut req_data: ResponseData;
+    pub async fn post_v(&self, request_path: String, params: BTreeMap<&str, &str>) -> Result<ResponseData, reqwest::Error> {
+        let  req_data: ResponseData;
         /*请求接口与 地址*/
         let url = format!("{}{}", self.base_url.to_string(), request_path);
         let req = self.client
@@ -124,24 +106,9 @@ impl RestTool {
             //println!("okx_order-Request failed with status: {}", body);
             req_data = ResponseData::error(body.to_string())
         }
-        Ok((req_data))
-    }
-
-
-    pub async fn delete(&self, params: BTreeMap<&str, &str>) -> Result<Response, reqwest::Error> {
-        let url = "https://jsonplaceholder.typicode.com/posts/1"; // 用您的URL替换此URL
-        let response = self.client.delete(url).send().await?;
-        Ok(response)
+        Ok(req_data)
     }
 
-    pub async fn put(&self, params: BTreeMap<&str, &str>) -> Result<Response, reqwest::Error> {
-        let url = "https://jsonplaceholder.typicode.com/posts/1"; // 用您的URL替换此URL
-        let mut data = HashMap::new();
-        data.insert("title", "foo");
-        data.insert("body", "bar");
-        let response = self.client.put(url).json(&data).send().await?;
-        Ok(response)
-    }
 
     //map数据转 get请求参数
     pub fn parse_params_to_str(parameters: BTreeMap<String, String>) -> String {

+ 2 - 2
exchanges/src/lib.rs

@@ -7,5 +7,5 @@ pub mod binance_spot_rest;
 pub mod binance_spot_ws;
 pub mod gate_spot_rest;
 pub mod gate_spot_ws;
-pub mod gate_usdt_swap_ws;
-pub mod gate_usdt_swap_rest;
+pub mod gate_swap_ws;
+pub mod gate_swap_rest;

+ 1 - 0
exchanges/src/proxy.rs

@@ -35,6 +35,7 @@ impl ParsingDetail {
     }
 
     //http请求是否开启代理:HTTP 只需要调用该方法即可
+    //原理是 设置全局代理,所以程序如果要走代理只需要执行一次,后续的get,post..都会走代理
     pub fn http_enable_proxy() -> bool {
         //拿到环境变量解析的数据
         let parsing_detail = Self::parsing_environment_variables();

+ 0 - 294
exchanges/src/ws_tool.rs

@@ -1,294 +0,0 @@
-use std::collections::BTreeMap;
-use std::future::Future;
-use std::{io, thread};
-use std::io::{Read, Write};
-use std::net::{IpAddr, Ipv4Addr, SocketAddr};
-use std::sync::Arc;
-use std::time::Duration;
-use chrono::Utc;
-use tokio::sync::Mutex;
-use crate::proxy;
-use crate::response_base::ResponseData;
-use tungstenite::client::{AutoStream, connect_with_proxy, ProxyAutoStream};
-use tungstenite::{connect, Message, WebSocket};
-use tungstenite::http::Response;
-use tungstenite::protocol::WebSocketConfig;
-use tungstenite::stream::Stream;
-use url::Url;
-
-/**socket请求工具*/
-pub struct SocketTool {
-    /*******参数*/
-    //连接地址
-    request_url: String,
-    //ip
-    ip: String,
-    //端口
-    port: u16,
-    //是否需要登陆
-    is_login: bool,
-    //登陆所需参数
-    login_param: BTreeMap<String, String>,
-    //订阅参数
-    subscription: serde_json::Value,
-
-    /*******响应钩子*/
-}
-
-
-impl SocketTool {
-    //装入配置获取
-    pub fn new(request_url: &str,
-               is_login: bool,
-               login_param: BTreeMap<String, String>,
-               subscription: serde_json::Value) -> SocketTool
-    {
-        let mut ip_v = "";
-        let mut port_v = 8080;
-        let mut v_str = String::from("");
-
-        /*******走代理:根据环境变量配置来决定,如果配置了走代理,没有配置不走*******/
-        let parsing_detail = proxy::ParsingDetail::parsing_environment_variables();
-        if parsing_detail.ip_address.len() > 0 && parsing_detail.port.len() > 0 {
-            ip_v = parsing_detail.ip_address.as_str();
-            port_v = parsing_detail.port.parse().unwrap();
-        }
-
-        /*****返回结构体*******/
-        SocketTool {
-            request_url: request_url.to_string(),
-            ip: ip_v.clone().to_string(),
-            port: port_v,
-            is_login,
-            login_param,
-            subscription,
-        }
-    }
-
-    pub fn run<OkText, F, Fut>(&self,
-                               ok_text: OkText,
-                               parse_fn: F)
-        where
-            OkText: Fn(String) -> ResponseData + 'static + Send + Sync,
-            F: Fn(ResponseData) -> Fut + 'static + Send + Sync,
-            Fut: Future<Output=()> + Send + 'static,
-    {
-        let parse_fn_arc = Arc::new(Mutex::new(parse_fn)); // Wrap the closure in an Arc<Mutex<_>>
-        loop {
-            let request_url = Url::parse(self.request_url.as_str()).unwrap();
-            //1. 判断是否需要代理,根据代理地址是否存来选择
-            if self.ip.len() > 0 {
-                let ip_array: Vec<&str> = self.ip.split(".").collect();
-                let proxy_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(
-                    ip_array[0].parse().unwrap(),
-                    ip_array[1].parse().unwrap(),
-                    ip_array[2].parse().unwrap(),
-                    ip_array[3].parse().unwrap())
-                ), self.port);
-                let websocket_config = Some(WebSocketConfig {
-                    max_send_queue: Some(16),
-                    max_message_size: Some(16 * 1024 * 1024),
-                    max_frame_size: Some(16 * 1024 * 1024),
-                    accept_unmasked_frames: false,
-                });
-                let max_redirects = 5;
-                // let (mut socket, response) =
-                let mut proxy_ws =
-                    connect_with_proxy(request_url.clone(), proxy_address, websocket_config, max_redirects)
-                        .expect("Can't connect(无法连接)");
-                Self::proxy_subscription(self, proxy_ws.0, &ok_text, &parse_fn_arc);
-            } else {
-                // let (mut socket, response) =
-                let mut no_proxy_ws =
-                    connect(request_url.clone())
-                        .expect("Can't connect(无法连接)");
-                Self::subscription(self, no_proxy_ws.0, &ok_text, &parse_fn_arc);
-            }
-        }
-    }
-
-    //代理-推送
-    fn proxy_subscription<OkText, F, Fut>(socket_tool: &SocketTool,
-                                          mut web_socket: WebSocket<ProxyAutoStream>,
-                                          ok_text: &OkText,
-                                          parse_fn: &Arc<Mutex<F>>,
-    )
-        where
-            OkText: Fn(String) -> ResponseData + 'static + Send + Sync,
-            F: Fn(ResponseData) -> Fut + 'static + Send + Sync,
-            Fut: Future<Output=()> + Send + 'static,
-
-    {
-        /*****消息溜***/
-        let mut stdout = io::stdout();
-        let mut stderr = io::stderr();
-        /******订阅信息********/
-        let sub_json = socket_tool.subscription.clone();
-        println!("--订阅内容:{:?}", sub_json);
-        let sub_json_str = sub_json.to_string();
-        web_socket.write_message(Message::Text(sub_json_str))
-            .unwrap();
-        loop {
-            let msg = web_socket.read_message();
-            match msg {
-                Ok(Message::Text(text)) => {
-                    let req_data = ok_text(text);
-                    writeln!(stdout, "Pong-响应--{:?}", req_data).unwrap();
-                    let parse_fn_clone = Arc::clone(parse_fn); // Clone the Arc for each iteration
-                    tokio::spawn(async move {
-                        let parse_fn_lock = parse_fn_clone.lock().await;
-                        parse_fn_lock(req_data).await;
-                    });
-
-                }
-                Ok(Message::Ping(s)) => {
-                    println!("Ping-响应--{:?}", String::from_utf8(s));
-                }
-                Ok(Message::Pong(s)) => {
-                    println!("Pong-响应--{:?}", String::from_utf8(s));
-                }
-                Ok(Message::Close(_)) => {
-                    println!("socket 关闭: ");
-                }
-                Err(error) => {
-                    println!("Error receiving message: {}", error);
-                    break;
-                }
-                _ => {}
-            }
-        }
-        web_socket.close(None).unwrap();
-    }
-    //非代理-推送
-    fn subscription<OkText, F, Fut>(socket_tool: &SocketTool, mut web_socket: WebSocket<AutoStream>,
-                                    ok_text: &OkText,
-                                    parse_fn: &Arc<Mutex<F>>,
-    )
-        where
-            OkText: Fn(String) -> ResponseData + 'static + Send + Sync,
-            F: Fn(ResponseData) -> Fut + 'static + Send + Sync,
-            Fut: Future<Output=()> + Send + 'static,
-    {
-        /*****消息溜***/
-        let mut stdout = io::stdout();
-        let mut stderr = io::stderr();
-        /******订阅信息********/
-        let sub_json = socket_tool.subscription.clone();
-        println!("--订阅内容:{:?}", sub_json);
-        let sub_json_str = sub_json.to_string();
-        web_socket.write_message(Message::Text(sub_json_str))
-            .unwrap();
-        loop {
-            let msg = web_socket.read_message();
-            match msg {
-                Ok(Message::Text(text)) => {
-                    let req_data = ok_text(text);
-                    writeln!(stdout, "Pong-响应--{:?}", req_data).unwrap();
-                    let parse_fn_clone = Arc::clone(parse_fn); // Clone the Arc for each iteration
-                    tokio::spawn(async move {
-                        let parse_fn_lock = parse_fn_clone.lock().await;
-                        parse_fn_lock(req_data).await;
-                    });
-
-                }
-                Ok(Message::Ping(s)) => {
-                    println!("Ping-响应--{:?}", String::from_utf8(s));
-                }
-                Ok(Message::Pong(s)) => {
-                    println!("Pong-响应--{:?}", String::from_utf8(s));
-                }
-                Ok(Message::Close(_)) => {
-                    println!("socket 关闭: ");
-                }
-                Err(error) => {
-                    println!("Error receiving message: {}", error);
-                    break;
-                }
-                _ => {}
-            }
-        }
-        web_socket.close(None).unwrap();
-    }
-
-
-    //访问---测试示例
-    pub fn run_lz(&self)
-    {
-        /*****消息溜***/
-        let mut stdout = io::stdout();
-        let mut stderr = io::stderr();
-
-        /*****socket配置信息***/
-        let request_url = Url::parse(self.request_url.as_str()).unwrap();
-        // let parse_fn = Arc::new(Mutex::new(parse_fn)); // Wrap the closure in an Arc<Mutex<_>>
-        let login_param = self.login_param.clone();
-        let lable = login_param.get("lable").unwrap().clone();
-
-        /*****判断代理IP是否为空,空则不走代理*****/
-        if self.ip.len() > 0 {
-            //println!("----socket-走代理");
-            let ip_array: Vec<&str> = self.ip.split(".").collect();
-            let proxy_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(
-                ip_array[0].parse().unwrap(),
-                ip_array[1].parse().unwrap(),
-                ip_array[2].parse().unwrap(),
-                ip_array[3].parse().unwrap())
-            ), self.port);
-            let websocket_config = Some(WebSocketConfig {
-                max_send_queue: Some(16),
-                max_message_size: Some(16 * 1024 * 1024),
-                max_frame_size: Some(16 * 1024 * 1024),
-                accept_unmasked_frames: false,
-            });
-            let max_redirects = 5;
-            let (mut socket, response) =
-                connect_with_proxy(request_url.clone(), proxy_address, websocket_config, max_redirects)
-                    .expect("Can't connect(无法连接)");
-
-            /******登陆认证********/
-            // if self.is_login {
-            //     //println!("----需要登陆");
-            //     let login_json_str = SocketTool::log_in_to_str(login_param);
-            //     // //println!("---组装 登陆信息:{0}", login_json_str);
-            //     socket.write_message(Message::Text(login_json_str)).unwrap();
-            //     thread::sleep(Duration::from_secs(1));
-            // } else {
-            //     //println!("----no longin(不需要登陆)");
-            // }
-
-            /******订阅信息********/
-            let sub_json = self.subscription.clone();
-            println!("--订阅内容:{:?}", sub_json);
-            let sub_json_str = sub_json.to_string();
-            // writeln!(stdout, "subscribe info: {:?}", sub_json_str).unwrap();
-            socket.write_message(Message::Text(sub_json_str))
-                .unwrap();
-
-            /******数据读取********/
-            loop {
-                let msg = socket.read_message();
-                //数据解析
-                match msg {
-                    Ok(Message::Text(text)) => {
-                        println!("???{:?}", text)
-                    }
-                    Ok(Message::Ping(s)) => {
-                        println!("Ping-响应--{:?}", String::from_utf8(s));
-                    }
-                    Ok(Message::Pong(s)) => {
-                        println!("Pong-响应--{:?}-{:?}", String::from_utf8(s), lable.to_string());
-                    }
-                    Ok(Message::Close(_)) => {
-                        println!("socket 关闭: ");
-                    }
-                    Err(error) => {
-                        println!("Error receiving message: {}", error);
-                        break;
-                    }
-                    _ => {}
-                }
-            }
-            socket.close(None).unwrap();
-        }
-    }
-}

+ 16 - 18
exchanges/tests/test.rs

@@ -1,25 +1,23 @@
 use std::collections::BTreeMap;
-use std::io;
-use exchanges::binance_usdt_swap_ws;
-use exchanges::binance_usdt_swap_ws::BinanceUsdtSwapWs;
-use exchanges::response_base::ResponseData;
-use std::io::{Read, Write};
+use exchanges::gate_swap_rest::GateSwapRest;
 
 #[tokio::test]
  async fn test_import() {
-    //币安---深度socket-公共频道订阅
-    let get_res_data = move |res_data: ResponseData| {
-        async move {
-            // println!("?????{:?}", res_data);
-            let mut stdout = io::stdout();
-            writeln!(stdout, "?????-响应--{:?}", res_data).unwrap();
-        }
-    };
-
-
+    //gate-rest -账户信息
     let mut btree_map: BTreeMap<String, String> = BTreeMap::new();
-    // btree_map.insert("lable".parse().unwrap(), "binance".parse().unwrap());//交易行名称
+    btree_map.insert("access_key".to_string(), "".to_string());
+    btree_map.insert("secret_key".to_string(), "".to_string());
+
+    let gate_exc = GateSwapRest::new(false, true, btree_map);
+    // let req_data = gate_exc.get_account("usdt".to_string()).await;
+    // println!("gate-rest -账户信息{:?}", req_data);
+    // let req_data = gate_exc.get_position("usdt".to_string(), "BTC_USDT".to_string()).await;
+    // println!("gate-rest -持仓信息{:?}", req_data);
+    // let req_data = gate_exc.get_ticker("usdt".to_string()).await;
+    // println!("gate-rest -ticker{:?}", req_data);
+   // let req_data = gate_exc.get_market_details("usdt".to_string()).await;
+   // println!("gate-rest -market_details{:?}", req_data);
+    let req_data = gate_exc.get_server_time().await;
+    println!("gate-rest -market_details{:?}", req_data);
 
-    let ba_exc = BinanceUsdtSwapWs::new(false, true, btree_map);
-    ba_exc.kline(vec![&"BTCUSDT"], get_res_data);
 }

+ 2 - 2
standard/src/gate_swap.rs

@@ -4,8 +4,8 @@ use async_trait::async_trait;
 use rust_decimal_macros::dec;
 use crate::utils;
 use crate::{Platform, ExchangeEnum, Account, Depth, MarketOrder};
-use exchanges::gate_usdt_swap_rest::GateUsdtSwapRest;
-use exchanges::gate_usdt_swap_ws::GateUsdtSwapWs;
+use exchanges::gate_swap_rest::GateUsdtSwapRest;
+use exchanges::gate_swap_ws::GateUsdtSwapWs;
 use exchanges::response_base::ResponseData;
 
 #[allow(dead_code)]