示例#1
0
        protected virtual SocketConnection BitMaxGetWebsocket(string address, bool authenticated)
        {
            address = address.TrimEnd('/');
            var socketResult = sockets.Where(s =>
                                             s.Value.Socket.Url.TrimEnd('/') == address.TrimEnd('/') &&
                                             (s.Value.Authenticated == authenticated || !authenticated) &&
                                             s.Value.Connected).OrderBy(s => s.Value.HandlerCount).FirstOrDefault();
            var result = socketResult.Equals(default(KeyValuePair <int, SocketConnection>)) ? null : socketResult.Value;

            if (result != null)
            {
                if (result.HandlerCount < SocketCombineTarget || (sockets.Count >= MaxSocketConnections && sockets.All(s => s.Value.HandlerCount >= SocketCombineTarget)))
                {
                    // Use existing socket if it has less than target connections OR it has the least connections and we can't make new
                    return(result);
                }
            }

            // Create new socket
            var socket        = CreateSocket(address);
            var socketWrapper = new SocketConnection(this, socket);

            foreach (var kvp in genericHandlers)
            {
                var handler = SocketSubscription.CreateForIdentifier(kvp.Key, false, kvp.Value);
                socketWrapper.AddHandler(handler);
            }

            return(socketWrapper);
        }
示例#2
0
        public void SocketMessages_Should_BeProcessedInDataHandlers()
        {
            // arrange
            var client = new TestSocketClient(new SocketClientOptions("")
            {
                ReconnectInterval = TimeSpan.Zero, LogVerbosity = LogVerbosity.Debug
            });
            var socket = client.CreateSocket();

            socket.ShouldReconnect = true;
            socket.CanConnect      = true;
            socket.DisconnectTime  = DateTime.UtcNow;
            var    sub      = new SocketConnection(client, socket);
            var    rstEvent = new ManualResetEvent(false);
            JToken result   = null;

            sub.AddHandler(SocketSubscription.CreateForIdentifier("TestHandler", true, (connection, data) =>
            {
                result = data;
                rstEvent.Set();
            }));
            client.ConnectSocketSub(sub);

            // act
            socket.InvokeMessage("{\"property\": 123}");
            rstEvent.WaitOne(1000);

            // assert
            Assert.IsTrue((int)result["property"] == 123);
        }
示例#3
0
        /// <inheritdoc />
        protected override SocketConnection GetWebsocket(string address, bool authenticated)
        {
            // Override because signalr puts `/signalr/` add the end of the url
            var socketResult = sockets.Where(s => s.Value.Socket.Url == address + "/signalr/" && (s.Value.Authenticated == authenticated || !authenticated) && s.Value.Connected).OrderBy(s => s.Value.HandlerCount).FirstOrDefault();
            var result       = socketResult.Equals(default(KeyValuePair <int, SocketConnection>)) ? null : socketResult.Value;

            if (result != null)
            {
                if (result.HandlerCount < SocketCombineTarget || (sockets.Count >= MaxSocketConnections && sockets.All(s => s.Value.HandlerCount >= SocketCombineTarget)))
                {
                    // Use existing socket if it has less than target connections OR it has the least connections and we can't make new
                    return(result);
                }
            }

            // Create new socket
            var socket        = CreateSocket(address);
            var socketWrapper = new SocketConnection(this, socket);

            foreach (var kvp in genericHandlers)
            {
                socketWrapper.AddHandler(SocketSubscription.CreateForIdentifier(kvp.Key, false, kvp.Value));
            }
            return(socketWrapper);
        }
示例#4
0
        public void SocketMessages_Should_ContainOriginalDataIfEnabled(bool enabled)
        {
            // arrange
            var client = new TestSocketClient(new SocketClientOptions("")
            {
                ReconnectInterval = TimeSpan.Zero, LogLevel = LogLevel.Debug, OutputOriginalData = enabled
            });
            var socket = client.CreateSocket();

            socket.ShouldReconnect = true;
            socket.CanConnect      = true;
            socket.DisconnectTime  = DateTime.UtcNow;
            var    sub      = new SocketConnection(client, socket);
            var    rstEvent = new ManualResetEvent(false);
            string original = null;

            sub.AddSubscription(SocketSubscription.CreateForIdentifier(10, "TestHandler", true, (messageEvent) =>
            {
                original = messageEvent.OriginalData;
                rstEvent.Set();
            }));
            client.ConnectSocketSub(sub);

            // act
            socket.InvokeMessage("{\"property\": 123}");
            rstEvent.WaitOne(1000);

            // assert
            Assert.IsTrue(original == (enabled ? "{\"property\": 123}" : null));
        }
示例#5
0
        protected virtual SocketConnection OkexGetSocketConnection(string address, bool authenticated)
        {
            address = authenticated
                ? "wss://ws.okx.com:8443/ws/v5/private"
                : "wss://ws.okx.com:8443/ws/v5/public";

            if (DemoTradingService)
            {
                address = authenticated
                    ? "wss://wspap.okx.com:8443/ws/v5/private?brokerId=9999"
                    : "wss://wspap.okx.com:8443/ws/v5/public?brokerId=9999";
            }

            var socketResult = sockets
                               .Where(s =>
                                      s.Value.Socket.Url.TrimEnd('/') == address.TrimEnd('/') &&
                                      (s.Value.Authenticated == authenticated || !authenticated) &&
                                      s.Value.Connected)
                               .OrderBy(s => s.Value.SubscriptionCount)
                               .FirstOrDefault();
            var result = socketResult.Equals(default(KeyValuePair <int, SocketConnection>)) ? null : socketResult.Value;

            if (result != null)
            {
                if (result.SubscriptionCount < SocketCombineTarget || (sockets.Count >= MaxSocketConnections && sockets.All(s => s.Value.SubscriptionCount >= SocketCombineTarget)))
                {
                    // Use existing socket if it has less than target connections OR it has the least connections and we can't make new
                    return(result);
                }
            }

            // Create new socket
            var socket           = CreateSocket(address);
            var socketConnection = new SocketConnection(this, socket);

            socketConnection.UnhandledMessage += HandleUnhandledMessage;
            foreach (var kvp in genericHandlers)
            {
                var handler = SocketSubscription.CreateForIdentifier(NextId(), kvp.Key, false, kvp.Value);
                socketConnection.AddSubscription(handler);
            }

            return(socketConnection);
        }
示例#6
0
        public void UnsubscribingStream_Should_CloseTheSocket()
        {
            // arrange
            var client = new TestSocketClient(new SocketClientOptions("")
            {
                ReconnectInterval = TimeSpan.Zero, LogVerbosity = LogVerbosity.Debug
            });
            var socket = client.CreateSocket();

            socket.CanConnect = true;
            var sub = new SocketConnection(client, socket);

            client.ConnectSocketSub(sub);
            var ups = new UpdateSubscription(sub, SocketSubscription.CreateForIdentifier("Test", true, (d, a) => {}));

            // act
            client.Unsubscribe(ups).Wait();

            // assert
            Assert.IsTrue(socket.Connected == false);
        }
示例#7
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));
        }