Example #1
0
        private static async Task ReceiveAsync(WebSocket webSocket, IWebSocketsClient client)
        {
            var buffer = new byte[1024 * 4];
            var result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);

            while (!result.CloseStatus.HasValue)
            {
                var data = buffer.Slice(0, result.Count);
                await client.ReceiveAsync(data);

                result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
            }

            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
        }
Example #2
0
        public static async Task ReceiveAsync(this WebSocket webSocket, IWebSocketsClient client)
        {
            int currentMessageLength = 0;

            byte[] buffer       = new byte[1024 * 4];
            byte[] combinedData = Array.Empty <byte>();

            WebSocketReceiveResult        result = null;
            Task <WebSocketReceiveResult> receiveBeforeTheLoop = webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
            await receiveBeforeTheLoop.ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    // TODO: how to log it from here
                }

                if (t.IsCompletedSuccessfully)
                {
                    result = t.Result;
                }
            });

            if (result == null)
            {
                // TODO: how to log it from here
                return;
            }

            while (result.MessageType != WebSocketMessageType.Close)
            {
                int newMessageLength = currentMessageLength + result.Count;
                if (newMessageLength > _maxPooledSize)
                {
                    throw new InvalidOperationException("Message too long");
                }

                byte[] newBytes = ArrayPool <byte> .Shared.Rent(newMessageLength);

                buffer.AsSpan(0, result.Count).CopyTo(newBytes.AsSpan(currentMessageLength, result.Count));
                if (!ReferenceEquals(combinedData, Array.Empty <byte>()))
                {
                    combinedData.AsSpan(0, currentMessageLength).CopyTo(newBytes.AsSpan(0, currentMessageLength));
                    ArrayPool <byte> .Shared.Return(combinedData);
                }

                combinedData         = newBytes;
                currentMessageLength = newMessageLength;

                if (result.EndOfMessage)
                {
                    Memory <byte> data = combinedData.AsMemory().Slice(0, currentMessageLength);
                    await client.ReceiveAsync(data);

                    currentMessageLength = 0;
                    ArrayPool <byte> .Shared.Return(combinedData);

                    combinedData = Array.Empty <byte>();
                }

                Task <WebSocketReceiveResult> receiveInTheLoop = webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);
                await receiveInTheLoop.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        result = null;
                        // TODO: how to log it from here
                    }

                    if (t.IsCompletedSuccessfully)
                    {
                        result = t.Result;
                    }
                });

                if (result == null)
                {
                    // TODO: how to log it from here
                    return;
                }
            }

            await webSocket.CloseAsync(result.CloseStatus ?? WebSocketCloseStatus.Empty, result.CloseStatusDescription, CancellationToken.None);
        }