예제 #1
0
        /// <inheritdoc />
        protected override async Task <CallResult <UpdateSubscription> > Subscribe <T>(string url, object?request, string?identifier, bool authenticated, Action <T> dataHandler)
        {
            SocketConnection?  socket;
            SocketSubscription handler;
            var released = false;
            await semaphoreSlim.WaitAsync().ConfigureAwait(false);

            try
            {
                socket = GetWebsocket(url, authenticated);
                if (socket == null)
                {
                    KucoinToken          token;
                    var                  clientOptions   = KucoinClient.DefaultOptions.Copy();
                    KucoinApiCredentials?thisCredentials = (KucoinApiCredentials?)authProvider?.Credentials;
                    if (thisCredentials != null)
                    {
                        clientOptions.ApiCredentials = new KucoinApiCredentials(thisCredentials.Key !.GetString(),
                                                                                thisCredentials.Secret !.GetString(), thisCredentials.PassPhrase.GetString());
                    }

                    using (var restClient = new KucoinClient(clientOptions))
                    {
                        var tokenResult = restClient.GetWebsocketToken(authenticated).Result;
                        if (!tokenResult)
                        {
                            return(new CallResult <UpdateSubscription>(null, tokenResult.Error));
                        }
                        token = tokenResult.Data;
                    }

                    // Create new socket
                    var s = CreateSocket(token.Servers.First().Endpoint + "?token=" + token.Token);
                    socket = new SocketConnection(this, s);
                    foreach (var kvp in genericHandlers)
                    {
                        socket.AddHandler(SocketSubscription.CreateForIdentifier(kvp.Key, false, kvp.Value));
                    }
                }

                handler = AddHandler(request, identifier, true, socket, dataHandler);
                if (SocketCombineTarget == 1)
                {
                    // Can release early when only a single sub per connection
                    semaphoreSlim.Release();
                    released = true;
                }

                var connectResult = await ConnectIfNeeded(socket, authenticated).ConfigureAwait(false);

                if (!connectResult)
                {
                    return(new CallResult <UpdateSubscription>(null, connectResult.Error));
                }
            }
            finally
            {
                //When the task is ready, release the semaphore. It is vital to ALWAYS release the semaphore when we are ready, or else we will end up with a Semaphore that is forever locked.
                //This is why it is important to do the Release within a try...finally clause; program execution may crash or take a different path, this way you are guaranteed execution
                if (!released)
                {
                    semaphoreSlim.Release();
                }
            }


            if (request != null)
            {
                var subResult = await SubscribeAndWait(socket, request, handler).ConfigureAwait(false);

                if (!subResult)
                {
                    await socket.Close(handler).ConfigureAwait(false);

                    return(new CallResult <UpdateSubscription>(null, subResult.Error));
                }
            }
            else
            {
                handler.Confirmed = true;
            }

            socket.ShouldReconnect = true;
            return(new CallResult <UpdateSubscription>(new UpdateSubscription(socket, handler), null));
        }
예제 #2
0
 /// <summary>
 /// Create a new order book instance
 /// </summary>
 /// <param name="symbol">The symbol the order book is for</param>
 /// <param name="options">The options for the order book</param>
 public KucoinSymbolOrderBook(string symbol, KucoinOrderBookOptions?options = null) : base(symbol, options ?? new KucoinOrderBookOptions())
 {
     restClient   = new KucoinClient();
     socketClient = new KucoinSocketClient();
 }