Exemplo n.º 1
0
        public static async Task CloseSocketAndThrow(ArraySegment <byte> buffer, ClientWebSocket socket, WebSocketCloseStatus status, string description, CancellationToken cancellation)
        {
            var array = buffer.Array;

            if (array.Length != WebsocketHelper.ORIGINAL_BUFFER_SIZE)
            {
                Array.Resize(ref array, WebsocketHelper.ORIGINAL_BUFFER_SIZE);
            }
            await WebsocketHelper.CloseSocket(socket, status, description, cancellation);

            throw new WebSocketException($"The socket has been closed ({status}: {description})");
        }
 public async void Dispose()
 {
     _cts.Cancel();
     await WebsocketHelper.CloseSocket(socket);
 }
 public async Task DisposeAsync()
 {
     _cts.Cancel();
     await WebsocketHelper.CloseSocket(socket);
 }
        protected async Task <string> WaitMessage(CancellationToken cancellation = default(CancellationToken))
        {
            var buffer       = _Buffer;
            var array        = _Buffer.Array;
            var originalSize = _Buffer.Array.Length;
            var newSize      = _Buffer.Array.Length;

            try
            {
                using var linkedCancel = CancellationTokenSource.CreateLinkedTokenSource(cancellation, _cts.Token);
                while (true)
                {
                    var message = await socket.ReceiveAsync(buffer, linkedCancel.Token);

                    if (message.MessageType == WebSocketMessageType.Close)
                    {
                        await WebsocketHelper.CloseSocketAndThrow(buffer, socket, WebSocketCloseStatus.NormalClosure, "Close message received from the peer", cancellation);

                        break;
                    }
                    if (message.MessageType != WebSocketMessageType.Text)
                    {
                        await WebsocketHelper.CloseSocketAndThrow(buffer, socket, WebSocketCloseStatus.InvalidMessageType, "Only Text is supported", cancellation);

                        break;
                    }
                    if (message.EndOfMessage)
                    {
                        buffer = new ArraySegment <byte>(array, 0, buffer.Offset + message.Count);
                        try
                        {
                            var o = WebsocketHelper.GetStringFromBuffer(buffer);
                            if (newSize != originalSize)
                            {
                                Array.Resize(ref array, originalSize);
                            }
                            return(o);
                        }
                        catch (Exception ex)
                        {
                            await WebsocketHelper.CloseSocketAndThrow(buffer, socket, WebSocketCloseStatus.InvalidPayloadData, $"Invalid payload: {ex.Message}", cancellation);
                        }
                    }
                    else
                    {
                        if (buffer.Count - message.Count <= 0)
                        {
                            newSize *= 2;
                            if (newSize > WebsocketHelper.MAX_BUFFER_SIZE)
                            {
                                await WebsocketHelper.CloseSocketAndThrow(buffer, socket, WebSocketCloseStatus.MessageTooBig, "Message is too big", cancellation);
                            }
                            Array.Resize(ref array, newSize);
                            buffer = new ArraySegment <byte>(array, buffer.Offset, newSize - buffer.Offset);
                        }
                        buffer = new ArraySegment <byte>(buffer.Array, buffer.Offset + message.Count, buffer.Count - message.Count);
                    }
                }
            }
            catch (Exception) when(_cts.IsCancellationRequested)
            {
                throw new OperationCanceledException(_cts.Token);
            }
            throw new InvalidOperationException("Should never happen");
        }