Quellcode durchsuchen

binan 接口提交

875428575@qq.com vor 2 Jahren
Ursprung
Commit
bfbd497e07
2 geänderte Dateien mit 176 neuen und 42 gelöschten Zeilen
  1. 0 1
      Cargo.toml
  2. 176 41
      src/exchange_libs.rs

+ 0 - 1
Cargo.toml

@@ -26,4 +26,3 @@ base64 = "0.13"
 #sha2 = "0.9"
 hex = "0.4"
 ring = "0.17.0-alpha.11"
-

+ 176 - 41
src/exchange_libs.rs

@@ -1,8 +1,10 @@
 use std::collections::{BTreeMap, HashMap};
-use std::{env, io};
+use std::{env, io, thread};
 use std::io::{Stdout, Write};
 use std::net::{IpAddr, Ipv4Addr, SocketAddr};
 use std::str::FromStr;
+use std::time::Duration;
+use chrono::Utc;
 use reqwest;
 use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT};
 use hex;
@@ -11,10 +13,10 @@ use ring::hmac;
 use serde_json::{json, Value};
 use serde_json::map::Values;
 use tungstenite::client::{AutoStream, connect_with_proxy, ProxyAutoStream};
-use tungstenite::{Message, WebSocket};
+use tungstenite::{connect, Message, WebSocket};
 use tungstenite::protocol::WebSocketConfig;
 use url::Url;
-
+use tungstenite::stream::Stream;
 // use std::io::{self, Write,io};
 
 
@@ -112,13 +114,13 @@ mod tests {
 
 pub struct BinanceExc {
     base_url: String,
-    access_keu: String,
+    access_key: String,
     secret_key: String,
 }
 
 impl BinanceExc {
-    pub fn new(access_keu: String, secret_key: String) -> BinanceExc {
-        BinanceExc { base_url: "https://api.binance.com".to_string(), access_keu, secret_key }
+    pub fn new(access_key: String, secret_key: String) -> BinanceExc {
+        BinanceExc { base_url: "https://api.binance.com".to_string(), access_key, secret_key }
     }
 
     //币安-深度信息
@@ -204,7 +206,7 @@ impl OkxExc {
 
         match result {
             Ok(req_data) => {
-                if (req_data.code != "0") {
+                if req_data.code != "0" {
                     req_data
                 } else {
                     let body: String = req_data.data;
@@ -239,7 +241,7 @@ impl OkxExc {
 
         match result {
             Ok(req_data) => {
-                if (req_data.code != "0") {
+                if req_data.code != "0" {
                     req_data
                 } else {
                     let body: String = req_data.data;
@@ -278,7 +280,7 @@ impl OkxExc {
 
         match result {
             Ok(req_data) => {
-                if (req_data.code != "0") {
+                if req_data.code != "0" {
                     req_data
                 } else {
                     let body: String = req_data.data;
@@ -311,7 +313,7 @@ impl OkxExc {
         ).await;
         match result {
             Ok(req_data) => {
-                if (req_data.code != "0") {
+                if req_data.code != "0" {
                     req_data
                 } else {
                     let body: String = req_data.data;
@@ -539,27 +541,43 @@ impl ReqData {
 }
 
 
+type HookFn = fn(String);
+
+
 pub struct SocketTool {
+    //连接地址
     request_url: String,
+    //ip
     ip: String,
+    //ip
     port: u16,
+    //是否需要登陆
     is_login: bool,
+    //登陆所需参数
+    login_param: BTreeMap<String, String>,
+    //订阅参数
     subscription: serde_json::Value,
+    //回调
+    hook_fn: HookFn,
 }
 
 impl SocketTool {
-    pub fn new(request_url: &str, is_login: bool, subscription: serde_json::Value) -> SocketTool {
+    pub fn new(request_url: &str,
+               is_login: bool,
+               login_param: BTreeMap<String, String>,
+               subscription: serde_json::Value,
+               hookfn: HookFn,
+    ) -> SocketTool {
         let mut ip_v = "";
         let mut port_v = 8080;
         let mut v_str = String::from("");
 
-        //拿到本机环境变量,
+        /*******读取环境变量-判定初始化代理地址*******/
         let env_var_name = "http_proxy";
         // 使用std::env::var函数获取环境变量的值,如果返回Err,则说明环境变量不存在
-
         match env::var(env_var_name) {
             Ok(value) => {
-                println!("Environment variable {} exists with value: {}", env_var_name, value);
+                // println!("Environment variable {} exists with value: {}", env_var_name, value);
                 v_str = value.clone();
                 if v_str.len() > 0 {
                     let parts: Vec<&str> = v_str.split("//").collect();
@@ -567,63 +585,130 @@ impl SocketTool {
                     ip_v = ip_port[0];
                     port_v = ip_port[1].parse().unwrap();
                 }
-                //http://127.0.0.1:7890
                 println!("代理设置成功{0},{1}", ip_v.to_string(), port_v.to_string());
             }
             Err(_) => {
-                println!("Environment variable {} does not exist.", env_var_name);
+                println!("环境变量 {} 不存在,无法开启代理.", env_var_name);
             }
         }
 
+        /*****返回结构体*******/
         SocketTool {
             request_url: request_url.to_string(),
             ip: ip_v.clone().to_string(),
             port: port_v,
             is_login: is_login,
+            login_param: login_param,
             subscription: subscription,
+            hook_fn: hookfn,
         }
     }
     pub fn run(&self) {
-        //订阅内容
-        let sub_json = self.subscription.clone();
-
+        /*****消息溜***/
         let mut stdout = io::stdout();
         let mut stderr = io::stderr();
+
+        /*****socket配置信息***/
         let request_url = Url::parse(self.request_url.as_str()).unwrap();
+        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;
+        /*****判断代理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, proxy_address, websocket_config, max_redirects)
-                    .expect("Can't connect");
+                    .expect("Can't connect(无法连接)");
+
+            /******登陆认证********/
+            if self.is_login {
+                println!("----需要登陆");
+                let lable = self.login_param.get("lable");
+
+                let login_json_str = self.log_in_to_str();
+                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();
 
+            /******数据读取********/
+            let mut  z_time  = Utc::now().timestamp() ;
+            loop {
+                if !socket.can_read() {
+                    continue;
+                }
+
+                let msg = socket.read_message();
+
+                match msg {
+                    Ok(Message::Text(text)) => {
+                        writeln!(stdout, "{:?}", text).unwrap();
+                        (self.hook_fn)("mamamimya".to_string());
+                    }
+                    Ok(Message::Ping(_)) | Ok(Message::Pong(_)) | Ok(Message::Close(_)) => {
+                        socket.write_message(Message::text("pong"));
+                        // writeln!(stdout, "ping----------pong").unwrap();
+                        writeln!(stdout, "ping----------pong").unwrap();
+                    }
+                    Err(error) => {
+                        writeln!(stderr, "Error receiving message: {}", error).unwrap();
+                        break;
+                    }
+                    _ => {}
+                }
+            }
+
+            socket.close(None).unwrap();
+        } else {
+            // 提示,并未找到好的优化方式,
+            println!("----socket-没代理");
+            let (mut socket, response) =
+                connect(request_url)
+                    .expect("Can't connect(无法连接)");
+
+            /******登陆认证********/
             if self.is_login {
-                println!("----需要登陆")
+                println!("----需要登陆");
+                let lable = self.login_param.get("lable");
+
+                let login_json_str = self.log_in_to_str();
+                println!("---组装 登陆信息:{0}", login_json_str);
+                socket.write_message(Message::Text(login_json_str)).unwrap();
+                thread::sleep(Duration::from_secs(1));
             } else {
-                println!("----不需要登陆")
+                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 {
                 if !socket.can_read() {
                     continue;
@@ -634,6 +719,7 @@ impl SocketTool {
                 match msg {
                     Ok(Message::Text(text)) => {
                         writeln!(stdout, "{:?}", text).unwrap();
+                        (self.hook_fn)("mamamimya".to_string());
                     }
                     Ok(Message::Ping(_)) | Ok(Message::Pong(_)) | Ok(Message::Close(_)) => {
                         socket.write_message(Message::Pong(vec![]))
@@ -649,10 +735,59 @@ impl SocketTool {
             }
 
             socket.close(None).unwrap();
+        }
+    }
+    fn log_in_to_str(&self) -> String {
+        let mut login_json_str = String::from("");
+
+        //解析并且组装 认证信息
+        let lable = self.login_param.get("lable");
+        if let Some(ref_string) = lable {
+            if *ref_string == "binance" {
+                println!("----币安 暂不做登陆");
+            } else if *ref_string == "okx" {
+                let mut access_key: String = "".to_string();
+                let mut secret_key: String = "".to_string();
+                let mut passphrase: String = "".to_string();
+
+                for (key, value) in &self.login_param {
+                    println!("Key: {}, Value: {}", key, value);
+                    if key == "access_key" {
+                        access_key = value.parse().unwrap();
+                    } else if key == "secret_key" {
+                        secret_key = value.parse().unwrap();
+                    } else if key == "passphrase" {
+                        passphrase = value.parse().unwrap();
+                    }
+                }
+                let timestamp = Utc::now().timestamp().to_string();
+
+                // 时间戳 + 请求类型+ 请求参数字符串
+                let message = format!("{}GET{}", timestamp, "/users/self/verify");
+                println!("---message:{:?}", message);
+                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 mut sign = base64::encode(result);
+
+                let login_json = json!({
+                              "op": "login",
+                                "args": [{
+                                "apiKey": access_key,
+                                "passphrase": passphrase,
+                                "timestamp": timestamp,
+                                "sign": sign  }]
+                        });
+
+                // println!("---login_json:{0}", login_json.to_string());
+                println!("--登陆:{:?}", login_json);
+                login_json_str = login_json.to_string();
+            }
         } else {
-            // 其他情况下的赋值
-            println!("----socket-没代理");
+            println!("Option is None(lable 为None)");
         }
+
+
+        login_json_str
     }
 }