コード例 #1
0
        public static async Task <Message> Deserialize(Stream stream, CancellationToken cancellationToken)
        {
            // TypeModel.DeserializeWithLengthPrefix does not work. We'll do it ourselves.
            const int BufferCapacity = 256; // This is arbitrary.
            var       bufferWriter   = new System.Buffers.ArrayBufferWriter <byte>();
            var       expectedLength = await GetMessageLength(stream, cancellationToken).ConfigureAwait(false);

            while (bufferWriter.WrittenCount < expectedLength)
            {
                var buffer    = bufferWriter.GetMemory(BufferCapacity);
                var byteCount = await stream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false);

                bufferWriter.Advance(byteCount);
            }

            Debug.Assert(bufferWriter.WrittenCount == expectedLength, $"Expected {expectedLength}, but got {bufferWriter.WrittenCount}");
            return(TypeModel.Deserialize <Message>(bufferWriter.WrittenMemory));
        }
コード例 #2
0
ファイル: WebSocketApi.cs プロジェクト: Ibasa/Ripple
        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();
        }