Example #1
0
        private async Task <System.Text.Json.JsonElement> ReceiveAsync(HttpResponseMessage response)
        {
            var body = await response.Content.ReadAsStringAsync();

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var json   = System.Text.Json.JsonDocument.Parse(body);
                var result = json.RootElement.GetProperty("result");

                var status = result.GetProperty("status").GetString();
                if (status == "success")
                {
                    return(result);
                }
                else if (status == "error")
                {
                    var             error   = result.GetProperty("error").GetString();
                    var             request = result.GetProperty("request");
                    RippleException exception;
                    if (result.TryGetProperty("error_exception", out var element))
                    {
                        exception = new RippleSubmitRequestException(error, element.GetString(), request);
                    }
                    else
                    {
                        exception = new RippleRequestException(error, request);
                    }

                    throw exception;
                }
                else
                {
                    throw new NotSupportedException(string.Format("{0} not a supported status", status));
                }
            }
            else
            {
                throw new RippleException(body);
            }
        }
Example #2
0
        private async Task ReceiveLoop()
        {
            var response = new System.Buffers.ArrayBufferWriter <byte>();

            while (!cancellationTokenSource.IsCancellationRequested)
            {
                var buffer = response.GetMemory();
                try
                {
                    var result = await socket.ReceiveAsync(buffer, cancellationTokenSource.Token);

                    response.Advance(result.Count);
                    if (result.EndOfMessage)
                    {
                        var json = System.Text.Json.JsonDocument.Parse(response.WrittenMemory);

                        var type = json.RootElement.GetProperty("type").GetString();
                        if (type == "response")
                        {
                            var id     = json.RootElement.GetProperty("id").GetUInt32();
                            var status = json.RootElement.GetProperty("status").GetString();
                            if (status == "success")
                            {
                                lock (responses)
                                {
                                    if (responses.TryGetValue(id, out var task))
                                    {
                                        responses.Remove(id);
                                        task.SetResult(json.RootElement.GetProperty("result").Clone());
                                    }
                                }
                            }
                            else if (status == "error")
                            {
                                var             error   = json.RootElement.GetProperty("error").GetString();
                                var             request = json.RootElement.GetProperty("request").Clone();
                                RippleException exception;
                                if (json.RootElement.TryGetProperty("error_exception", out var element))
                                {
                                    exception = new RippleSubmitRequestException(error, element.GetString(), request);
                                }
                                else
                                {
                                    exception = new RippleRequestException(error, request);
                                }

                                lock (responses)
                                {
                                    if (responses.TryGetValue(id, out var task))
                                    {
                                        responses.Remove(id);
                                        task.SetException(exception);
                                    }
                                }
                            }
                            else
                            {
                                lock (responses)
                                {
                                    if (responses.TryGetValue(id, out var task))
                                    {
                                        responses.Remove(id);
                                        task.SetException(new NotSupportedException(string.Format("{0} not a supported status", status)));
                                    }
                                }
                            }
                        }
                        else if (type == "path_find")
                        {
                            var id = json.RootElement.GetProperty("id").GetUInt32();
                            var pathFindResponse = new PathFindResponse(json.RootElement);
                            try
                            {
                                OnPathFind?.Invoke(this, id, pathFindResponse);
                            }
                            catch (Exception exc)
                            {
                                // TODO: We don't want user exceptions from the OnPathFind event to tear down this thread but we should bubble them up somehow.
                            }
                        }

                        response.Clear();
                    }
                }
                catch (TaskCanceledException taskCanceledException)
                {
                    if (taskCanceledException.CancellationToken == cancellationTokenSource.Token)
                    {
                        // We canceled the receive, while loop will now terminate and task completes successfully
                    }
                    else
                    {
                        // Something else unexpected was cancelled, rethrow
                        throw;
                    }
                }
            }
            socket.Dispose();
        }