HttpClient异步等待测试Gemini.com API读取响应/内容?

时间:2016-10-25 16:11:11

标签: c# async-await

所以我试图测试来自Gemini的经过验证的回复。我得到了一个"响应",但不是我期望的......它以html字符串形式返回,而不是"一系列余额"就像我应该得到的API suggests一样。我之前没有使用过HttpClient,所以这里有双重学习曲线。不确定我是否有错误信息,或者我是否查看了错误的方法/属性?

我对如何从Gemini返回此数组感到有些困惑。

我有API Key和Secret,因为这只是在沙盒上。帐户有大约1,000,000个虚假资产。

JSON字符串

{"request":"/v1/balances","nonce":1477275934999}

JSON / Payload的Base64编码

eyJyZXF1ZXN0IjoiL3YxL2JhbGFuY2VzIiwibm9uY2UiOjE0NzcyNzU5MzQ5OTl9

发布消息

Method: POST, RequestUri: 'https://api.sandbox.gemini.com/', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
  X-GEMINI-APIKEY: L6qDKmQZcmLVDTd5zK9S
  X-GEMINI-PAYLOAD: eyJyZXF1ZXN0IjoiL3YxL2JhbGFuY2VzIiwibm9uY2UiOjE0NzcyNzU5MzQ5OTl9
  X-GEMINI-SIGNATURE: DBA15C6B2FFA602F9323E0180A14BABEA018640324E313D6C8BBAE9F8872B06325B75F6C507C55435982D600EE5DDF57
  Content-Type: text/plain; charset=utf-8
}

回复字符串:(似乎总是'工作',即使我有不正确的请求,我也没注意到一点)

StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Connection: keep-alive
  Age: 6605
  X-Cache: Hit from cloudfront
  X-Amz-Cf-Id: Ae3ps4mhbjIzGCrgFr43dq0ICZvnUmPKpeo1miv4ufDFJkJtNZy8GA==
  Date: Sat, 22 Oct 2016 22:55:51 GMT
  ETag: "5dc6bbdccdd2100c4ca4b0155402db35"
  Server: AmazonS3
  Via: 1.1 cae81d5ff1d682b28f2deabdd94777d4.cloudfront.net (CloudFront)
  Content-Length: 172
  Content-Type: text/html
  Last-Modified: Fri, 29 Jul 2016 18:31:06 GMT
}

Response.Content - 不是我的预期......

<html>
    <head>
        <script>
            window.location.replace("/rest-api/" + window.location.search + window.location.hash);
        </script>
    </head>
</html>

代码(C#.NET 4.5)

using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Gemini.API;
using Newtonsoft.Json;

namespace HodlBot
{
    class Program
    {
        public const int TIME_INTERVAL_IN_MILLISECONDS = 3000;
        private static Timer m_timer = null;

        private static void Main(string[] args)
        {
            var source = new CancellationTokenSource();
            Console.CancelKeyPress += (s, e) =>
            {
                e.Cancel = true;
                source.Cancel();
            };

            m_timer = new System.Threading.Timer(Tick, source, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite);

            source.Token.WaitHandle.WaitOne();
        }

        private async static void Tick(object p_state)
        {
            Console.Clear();
            var c = (CancellationTokenSource)p_state;

            /* All requests must contain a nonce, a number that will never be repeated and must increase between requests. This is to prevent an attacker who has
             * captured a previous request from simply replaying that request. We recommend using a millisecond-level timestamp. The nonce need only be
             * increasing with respect to the session that the message is on.*/

            long nonce = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            string jObject = JsonConvert.SerializeObject(new Balance(nonce));

            await POST(jObject);

            // Re-Prime Event
            if(!c.Token.IsCancellationRequested)
                m_timer.Change(TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite);
        }

        private static async Task POST(string jsonText)
        {
            // Sign Payload
            Console.WriteLine(jsonText);
            string payload = System.Convert.ToBase64String((Encoding.UTF8.GetBytes(jsonText)));

            Console.WriteLine(payload);

            HMACSHA384 hmac = new HMACSHA384(Encoding.UTF8.GetBytes("LixWGpx3h89D8B4uQvfxd8hy5N1"));           //My API SECRET
            byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
            string hexHash = BitConverter.ToString(hash).Replace("-", "");

            using(var httpClient = new HttpClient())
            using(var stringContent = new StringContent("", Encoding.UTF8, "text/plain"))
            using(var r = new HttpRequestMessage(HttpMethod.Post, "https://api.sandbox.gemini.com"))
            {
                r.Headers.Add("X-GEMINI-APIKEY", "L6qDKmQZcmLVDTd5zK9S");
                r.Headers.Add("X-GEMINI-PAYLOAD", payload);
                r.Headers.Add("X-GEMINI-SIGNATURE", hexHash);
                r.Content = stringContent;

                Console.WriteLine(r.ToString());

                var response = await httpClient.SendAsync(r);
                if(response.IsSuccessStatusCode)
                {
                    Console.WriteLine(response.ToString());
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(content);
                }
            }
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Gemini.API
{
    public class BasicRequest
    {
        [JsonProperty("request", Order = 1)]
        public string Request { get; internal set; }

        [JsonProperty("nonce", Order = 2)]
        public long Nonce { get; internal set; }

        public BasicRequest(string request, long nonce)
        {
            Request = request;
            Nonce = nonce;
        }
    }

    public class HeartBeat : BasicRequest
    {
        public HeartBeat(long nonce) : base("/v1/heartbeat", nonce) { }
    }


    public class Balance : BasicRequest
    {
        public Balance(long nonce) : base("/v1/balances", nonce) { }
    }
}

0 个答案:

没有答案