Ejemplo n.º 1
0
        private IObservable <PooledArraySegment <byte>[]> ZmqSubscribeEndpoint(DaemonEndpointConfig endPoint, string url, string topic, int numMsgSegments = 2)
        {
            return(Observable.Defer(() => Observable.Create <PooledArraySegment <byte>[]>(obs =>
            {
                var tcs = new CancellationTokenSource();

                Task.Factory.StartNew(() =>
                {
                    using (tcs)
                    {
                        while (!tcs.IsCancellationRequested)
                        {
                            try
                            {
                                using (var subSocket = new SubscriberSocket())
                                {
                                    //subSocket.Options.ReceiveHighWatermark = 1000;
                                    subSocket.Connect(url);
                                    subSocket.Subscribe(topic);

                                    logger.Debug($"Subscribed to {url}/{BitcoinConstants.ZmqPublisherTopicBlockHash}");

                                    while (!tcs.IsCancellationRequested)
                                    {
                                        var msg = subSocket.ReceiveMultipartMessage(numMsgSegments);

                                        // Export all frame data as array of PooledArraySegments
                                        var result = msg.Select(x =>
                                        {
                                            var buf = ArrayPool <byte> .Shared.Rent(x.BufferSize);
                                            Array.Copy(x.ToByteArray(), buf, x.BufferSize);
                                            return new PooledArraySegment <byte>(buf, 0, x.BufferSize);
                                        }).ToArray();

                                        obs.OnNext(result);
                                    }
                                }
                            }

                            catch (Exception ex)
                            {
                                logger.Error(ex);
                            }

                            // do not consume all CPU cycles in case of a long lasting error condition
                            Thread.Sleep(1000);
                        }
                    }
                }, tcs.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

                return Disposable.Create(() =>
                {
                    tcs.Cancel();
                });
            })));
        }
Ejemplo n.º 2
0
        private async Task <JsonRpcResponse <JToken>[]> BuildBatchRequestTask(DaemonEndpointConfig endPoint, DaemonCmd[] batch)
        {
            // build rpc request
            var rpcRequests = batch.Select(x => new JsonRpcRequest <object>(x.Method, x.Payload, GetRequestId()));

            // build request url
            var requestUrl = $"http://{endPoint.Host}:{endPoint.Port}";

            if (!string.IsNullOrEmpty(rpcLocation))
            {
                requestUrl += $"/{rpcLocation}";
            }

            // build http request
            using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
            {
                var json = JsonConvert.SerializeObject(rpcRequests, serializerSettings);
                request.Content = new StringContent(json, Encoding.UTF8, "application/json");

                // build auth header
                if (!string.IsNullOrEmpty(endPoint.User))
                {
                    var auth   = $"{endPoint.User}:{endPoint.Password}";
                    var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(auth));
                    request.Headers.Authorization = new AuthenticationHeaderValue("Basic", base64);
                }

                // send request
                var httpClient = httpClients[endPoint];

                using (var response = await httpClient.SendAsync(request))
                {
                    // check success
                    if (!response.IsSuccessStatusCode)
                    {
                        throw new DaemonClientException(response.StatusCode, response.ReasonPhrase);
                    }

                    // deserialize response
                    using (var stream = await response.Content.ReadAsStreamAsync())
                    {
                        using (var reader = new StreamReader(stream, Encoding.UTF8))
                        {
                            using (var jreader = new JsonTextReader(reader))
                            {
                                var result = serializer.Deserialize <JsonRpcResponse <JToken>[]>(jreader);
                                return(result);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private async Task <JsonRpcResponse> BuildRequestTask(DaemonEndpointConfig endPoint, string method, object payload,
                                                              JsonSerializerSettings payloadJsonSerializerSettings = null)
        {
            var rpcRequestId = GetRequestId();

            // build rpc request
            var rpcRequest = new JsonRpcRequest <object>(method, payload, rpcRequestId);

            // build request url
            var requestUrl = $"http://{endPoint.Host}:{endPoint.Port}";

            if (!string.IsNullOrEmpty(rpcLocation))
            {
                requestUrl += $"/{rpcLocation}";
            }

            // build http request
            var request = new HttpRequestMessage(HttpMethod.Post, requestUrl);
            var json    = JsonConvert.SerializeObject(rpcRequest, payloadJsonSerializerSettings ?? serializerSettings);

            request.Content = new StringContent(json, Encoding.UTF8, "application/json");

            // build auth header
            if (!string.IsNullOrEmpty(endPoint.User))
            {
                var auth   = $"{endPoint.User}:{endPoint.Password}";
                var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(auth));
                request.Headers.Authorization = new AuthenticationHeaderValue("Basic", base64);
            }

            // send request
            var httpClient = httpClients[endPoint];

            using (var response = await httpClient.SendAsync(request))
            {
                // deserialize response
                using (var stream = await response.Content.ReadAsStreamAsync())
                {
                    using (var reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        using (var jreader = new JsonTextReader(reader))
                        {
                            var result = serializer.Deserialize <JsonRpcResponse>(jreader);
                            return(result);
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
    public RpcClient(DaemonEndpointConfig endPoint, JsonSerializerSettings serializerSettings, IMessageBus messageBus, string poolId)
    {
        Contract.RequiresNonNull(serializerSettings, nameof(serializerSettings));
        Contract.RequiresNonNull(messageBus, nameof(messageBus));
        Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(poolId), $"{nameof(poolId)} must not be empty");

        config = endPoint;
        this.serializerSettings = serializerSettings;
        this.messageBus         = messageBus;
        this.poolId             = poolId;

        serializer = new JsonSerializer
        {
            ContractResolver = serializerSettings.ContractResolver !
        };
    }
Ejemplo n.º 5
0
        private IObservable <PooledArraySegment <byte> > WebsocketSubscribeEndpoint(DaemonEndpointConfig endPoint, int port, string method, object payload = null,
                                                                                    JsonSerializerSettings payloadJsonSerializerSettings = null)
        {
            return(Observable.Defer(() => Observable.Create <PooledArraySegment <byte> >(obs =>
            {
                var cts = new CancellationTokenSource();

                var thread = new Thread(async(_) =>
                {
                    using (cts)
                    {
                        while (!cts.IsCancellationRequested)
                        {
                            try
                            {
                                using (var plb = new PooledLineBuffer(logger))
                                {
                                    using (var client = new ClientWebSocket())
                                    {
                                        // connect
                                        var uri = new Uri($"ws://{endPoint.Host}:{port}");

                                        logger.Debug(() => $"Establishing WebSocket connection to {uri}");
                                        await client.ConnectAsync(uri, cts.Token);

                                        // subscribe
                                        var buf = ArrayPool <byte> .Shared.Rent(0x10000);

                                        try
                                        {
                                            var request = new JsonRpcRequest(method, payload, GetRequestId());
                                            var json = JsonConvert.SerializeObject(request, payloadJsonSerializerSettings).ToCharArray();
                                            var byteLength = Encoding.UTF8.GetBytes(json, 0, json.Length, buf, 0);
                                            var segment = new ArraySegment <byte>(buf, 0, byteLength);

                                            logger.Debug(() => $"Sending WebSocket subscription request to {uri}");
                                            await client.SendAsync(segment, WebSocketMessageType.Text, true, cts.Token);

                                            // stream response
                                            segment = new ArraySegment <byte>(buf);

                                            while (!cts.IsCancellationRequested && client.State == WebSocketState.Open)
                                            {
                                                var response = await client.ReceiveAsync(buf, cts.Token);

                                                if (response.MessageType == WebSocketMessageType.Binary)
                                                {
                                                    throw new InvalidDataException("expected text, received binary data");
                                                }

                                                plb.Receive(segment, response.Count,
                                                            (src, dst, count) => Array.Copy(src.Array, src.Offset, dst, 0, count),
                                                            obs.OnNext, (ex) => { }, response.EndOfMessage);
                                            }
                                        }

                                        finally
                                        {
                                            ArrayPool <byte> .Shared.Return(buf);
                                        }
                                    }
                                }
                            }

                            catch (Exception ex)
                            {
                                logger.Error(() => $"{ex.GetType().Name} '{ex.Message}' while streaming websocket responses. Reconnecting in 5s");
                            }

                            await Task.Delay(TimeSpan.FromSeconds(5), cts.Token);
                        }
                    }
                });

                thread.Start();

                return Disposable.Create(() =>
                {
                    cts.Cancel();
                });
            })));
        }