JKorf / Binance.Net

A C# .netstandard client library for the Binance REST and Websocket Spot and Futures API focusing on clear usage and models
https://jkorf.github.io/Binance.Net/
MIT License
1.04k stars 428 forks source link

Websocket example code not working #630

Closed Oshirowanen closed 3 years ago

Oshirowanen commented 3 years ago

I have installed the wrapper from https://github.com/JKorf/Binance.Net

Using their example code, I have the following in my app:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Binance.Net;
    using Binance.Net.Enums;
    using Binance.Net.Objects;
    using Binance.Net.Objects.Spot;
    using CryptoExchange.Net.Authentication;
    using CryptoExchange.Net.Logging;

    namespace binance_stream_user_data_updates
    {
        class Program
        {
            static void Main(string[] args)
            {
                var client = new BinanceClient(new BinanceClientOptions{
                    ApiCredentials = new ApiCredentials("key","secret"),
                    BaseAddress = "https://testnet.binance.vision",
                    LogVerbosity = LogVerbosity.Debug,
                    LogWriters = new List<TextWriter> { Console.Out }
                });

                var startResult = client.Spot.UserStream.StartUserStream();

                if(!startResult.Success)
                    throw new Exception($"Failed to start user stream: {startResult.Error}");

                var socketClient = new BinanceSocketClient();

                socketClient.Spot.SubscribeToUserDataUpdates(startResult.Data,
                null,
                data => {
                    Console.WriteLine(data.Orders);
                    },
                null,
                null);

                socketClient.UnsubscribeAll();

                Console.ReadLine();
            }
        }
    }

I then run the above app which seems to connect and starts waiting, as the following is shown in the terminal:

    dotnet run
    2021/02/26 20:36:51:863 | Binance    | Debug | Client configuration: LogVerbosity: Debug, Writers: 1, Credentials: Set, BaseAddress: https://testnet.binance.vision/, Proxy: -, RateLimiters: 0, RateLimitBehaviour: Wait, RequestTimeout: 00:00:30
    2021/02/26 20:36:51:903 | Binance    | Debug | [1] Creating request for https://testnet.binance.vision/api/v3/time
    2021/02/26 20:36:51:911 | Binance    | Debug | [1] Sending GET request to https://testnet.binance.vision/api/v3/time 
    2021/02/26 20:36:53:242 | Binance    | Debug | [1] Response received in 1320ms: {"serverTime":1614371813101}
    2021/02/26 20:36:53:345 | Binance    | Debug | [2] Creating request for https://testnet.binance.vision/api/v3/time
    2021/02/26 20:36:53:346 | Binance    | Debug | [2] Sending GET request to https://testnet.binance.vision/api/v3/time 
    2021/02/26 20:36:54:028 | Binance    | Debug | [2] Response received in 681ms: {"serverTime":1614371813881}
    2021/02/26 20:36:54:029 | Binance    | Info | Time offset set to 535.073ms
    2021/02/26 20:36:54:031 | Binance    | Debug | [3] Creating request for https://testnet.binance.vision/api/v1/userDataStream
    2021/02/26 20:36:54:037 | Binance    | Debug | [3] Sending POST request to https://testnet.binance.vision/api/v1/userDataStream with request body 
    2021/02/26 20:36:54:732 | Binance    | Debug | [3] Response received in 694ms: {"listenKey":"key"}

I then post an order

POST https://testnet.binance.vision/api/v3/order?symbol=BNBUSDT&side=SELL&type=MARKET&quantity=0.1&newClientOrderId=my_order_id_201&newOrderRespType=FULL&timestamp=1614370483356&signature=58cfd86cffc626703eac32f14bf0fa2e9af4850fb33974a03d1eee3f666df15f

When I do that, the websocket running from the above code outputs nothing. Does the example code need updating?

hosulik commented 3 years ago

Hi. I think, that your problems are:

  1. You create socketClient without defining ApiCreadentials and BaseAddress - this is the most important, because you want to use testing URL wss://testnet.binance.vision/ws,

  2. This line of code "socketClient.UnsubscribeAll();". You are immediately unsubscribing after subscribe, so you will never receive some update via websocket.

Oshirowanen commented 3 years ago

Hello,

You're right, I did change those 2 lines around, but it made no difference.

Since I posted that example code, I have noticed that the code works perfectly when using the binance mainnet, but it does nothing using the binance testnet. If I connect to the binance testnet and sent a buy/sell order, nothing is detected by the websocket code above.

Is the binance testnet broken?

Probably a question for binance instead of here.

hosulik commented 3 years ago

I tryied it today and it worked in testnet. I am looking now on your POST. You are posting normal order, however, you are waiting for onOcoOrderUpdateMessage - second action in SubscribeToUserDataUpdates method. You should use first action - onOrderUpdateMessage.

Hulkstance commented 3 years ago

Just a bit edited version.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Binance.Net;
using Binance.Net.Enums;
using Binance.Net.Objects;
using Binance.Net.Objects.Spot;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Logging;

namespace binance_stream_user_data_updates
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // TODO: Dispose BinanceClient and BinanceSocketClient at some point.
            var client = new BinanceClient(new BinanceClientOptions
            {
                ApiCredentials = new ApiCredentials("key", "secret"),
                AutoTimestamp = true,
                AutoTimestampRecalculationInterval = TimeSpan.FromMinutes(30),
                BaseAddress = "https://testnet.binance.vision",
                LogVerbosity = LogVerbosity.Debug,
                LogWriters = new List<TextWriter> { Console.Out }
            });

            var socketClient = new BinanceSocketClient(new BinanceSocketClientOptions
            {
                ApiCredentials = new ApiCredentials("key", "secret"),
                AutoReconnect = true,
                BaseAddress = "wss://testnet.binance.vision/ws",
                ReconnectInterval = TimeSpan.FromSeconds(15)
            });

            var listenKey = await client.Spot.UserStream.StartUserStreamAsync();

            if (!listenKey.Success)
                throw new Exception($"Failed to start user stream: {listenKey.Error}");

            var subscription = await socketClient.Spot.SubscribeToUserDataUpdatesAsync(listenKey.Data,
            null,
            data =>
            {
                Console.WriteLine(data.Orders);
            },
            null,
            null);

            if (!subscription.Success)
                throw new Exception($"Failed to subscribe to web socket stream: {listenKey.Error}");

            // TODO: Put a CancellationToken in order to stop it gracefully
            var keepAliveTask = Task.Run(async () =>
            {
                while (true)
                {
                    await client.Spot.UserStream.KeepAliveUserStreamAsync(listenKey.Data);
                    await Task.Delay(TimeSpan.FromMinutes(30));
                }
            });

            Console.ReadLine();
        }
    }
}
hosulik commented 3 years ago

I found these differences between your and my code:

var socketClient = new BinanceSocketClient(new BinanceSocketClientOptions { ApiCredentials = new ApiCredentials("apiKey", "secret"), BaseAddress = "wss://testnet.binance.vision/ws", AutoReconnect = true });

socketClient.Spot.SubscribeToUserDataUpdates(startResult.Data, onOrderUpdateMessage => { _logger.LogInformation("onOrderUpdateMessage: "); }, onOcoOrderUpdateMessage => { _logger.LogInformation("onOcoOrderUpdateMessage: "); }, onAccountPositionMessage => { _logger.LogInformation("onAccountPositionMessage: "); }, onAccountBalanceUpdate => { _logger.LogInformation("onAccountBalanceUpdate: "); });

I have not tried it with SubscribeUserDataUpdatesAsync yet, but the code above works for me.

Hulkstance commented 3 years ago

@hosulik, the code I posted, works just fine. I forgot to add BaseAddress to the web socket stream, but corrected it.

OP's way of creating orders is probably wrong.

var result = await client.Spot.Order.PlaceOrderAsync("TRXUSDT", OrderSide.Buy, OrderType.Market, quoteOrderQuantity: 100m).ConfigureAwait(false);
JKorf commented 3 years ago

Closing because of inactivity; if there are still issues let me know