glitch100 / BinanceDotNet

Official C# Wrapper for the Binance exchange API, with REST and WebSocket endpoints
https://www.nuget.org/packages/BinanceDotNet/
MIT License
161 stars 138 forks source link

Frequent disconnects #121

Open vburwitz3 opened 6 years ago

vburwitz3 commented 6 years ago

Issue Overview

Sadly there is a problem that connections get constantly lost if you run a program 24h. I do not see how to get that solved. If there are no price updates for some time I can rerequest. But UserDataWebSocketMessages connection handlers die and I cant check them (at least I do not see how) (and price updates may still be coming and are not broken!). Sadly everything is wrapped up in a DLL so I can not go into the problem. Telegram API discussion group or Binance ticket was of no use. The real problem is there is no working function to check if connection is ok. At the beginning each order creation/deletion on binance comes over the connection, at a certain point it stops until a connection is newly recreated (new UserDataWebSocketMessages()). The problem is there is also no exception or so that would be thrown to get the information that connection is broken.

Package Version: ?.?.?

BinanceDotNet 4.6.2

Repro Steps

To check the issue simply do a connection with new UserDataWebSocketMessage(OrderUpdateMessageHandler, TradeUpdateMessageHandler, AccountUpdateMessageHandler) and try after some hours to get a order update, by example cancelling an existing order over the Binance website "Open Orders" page. Mostly after some hours the connection will have died and there will be no Update/Cancellation/Whatever message received by the client anymore.

Other Information

It is a very severe API issue! Since it basically prevents implementing a stable automated trading application!

vburwitz3 commented 6 years ago

My request code it the following



private async void startBinanceConnection (bool requestUnderlyings) {
    // Binance init
    binanceClient   =new BinanceClient(new ClientConfiguration() {
        ApiKey      =binanceApiKey,
        SecretKey   =binanceSecretKey,
        Logger      =logger,
        DefaultReceiveWindow    =50000,
    });

    // init callbacks and start
    UserDataWebSocketMessages userDataWebSocketMessages =new UserDataWebSocketMessages {
        OrderUpdateMessageHandler   =new BinanceWebSocketMessageHandler<BinanceTradeOrderData>(x => {
            // OrderStatusUpdate() als EventHandler callen um Orderänderungen zu verarbeiten
            MethodInvoker orderStatusUpdateCall =delegate {
                OrderStatusUpdate(x);
            };
            Form1.gui.Invoke(orderStatusUpdateCall);
        }),
        TradeUpdateMessageHandler   =new BinanceWebSocketMessageHandler<BinanceTradeOrderData>(x => {
            // OrderStatusUpdate() als EventHandler callen um Trade Executions zu verarbeiten
            MethodInvoker orderStatusUpdateCall =delegate {
                OrderStatusUpdate(x);
            };
            Form1.gui.Invoke(orderStatusUpdateCall);
        }),
        AccountUpdateMessageHandler =new BinanceWebSocketMessageHandler<BinanceAccountUpdateData>(x => {
            Console.WriteLine("AccountUpdateMessageHandler: eventType " +x.EventType+" balances "+x.Balances.ToString());
        })
    };

    logger.Info("binanceWebSocketClient Callbacks starting...");
    binanceWebSocketClient      =new DisposableBinanceWebSocketClient(binanceClient, logger);
    try {
        binanceWebSocketClientGuid  =await binanceWebSocketClient.ConnectToUserDataWebSocket(userDataWebSocketMessages);
    }
    catch (Exception ex) {
        printMsgStatic("startBinanceConnection: ConnectToUserDataWebSocket failed (Exception: "+ex.Message+").");
    }
    logger.Info("binanceWebSocketClient Callbacks done.");

    if (requestUnderlyings) {
        printMsgStatic("Underlyings Requests start.");
        // alle Underlyings neu requesten
        for (int undID=0; undID<indexEntries.GetLength(0); undID++) {
            Underlying und      =(Underlying)symbols[undID];
            // Realtime Tickdaten für das Index Spot Underlying requesten
            printMsgStatic("Start Binance realtime Request: "+und.underlying);
            // Manual WebSocket usage
            var socketId    =binanceWebSocketClient.ConnectToTradesWebSocket(indexEntries[undID,indexSpot], b => {
                Form1.updateLastBinance(b);
            });
        } // for (underlying)
        printMsgStatic("Underlyings Requests done.");
    }
} // startBinanceConnection()
xfiodembo commented 5 years ago

Fortunately its not an issue, all websocket connections die at the 24h mark. at least per binance api docs "A single connection to stream.binance.com is only valid for 24 hours; expect to be disconnected at the 24 hour mark"

vburwitz3 commented 5 years ago

It is a issue. i found out that the connections die after about 3 minutes. And the documentation says that you need to send a Pong after eacjh Ping that was send (or simply frequently). The problem is that the "Listen Key" is not available over the API! When the connection is established just a Guid is returned and the Listen Key that would be available in the connection function is simply forgotten (just in a local object that is not stored or returned) and is for the API user unavailable.

glitch100 commented 5 years ago

@vburwitz3 Can you provide a link to documentation around the Listen Key?

vburwitz3 commented 5 years ago

I have not programmed it yet, since I am to stupid to get:

The current .NET SDK does not support targeting .NET Standard 2.0. Either target .NET Standard 1.6 or lower, or use a version of the .NET SDK that supports .NET Standard 2.0. BinanceExchange.API

in Visual Studio Express 2017 solved. Therefore I can not do so currently.