Example #1
0
        protected override async Task ProtectedWriteAsync(
            byte[] buffer,
            int offset,
            int count,
            CancellationToken cancellationToken)
        {
            VerifyConnectionNotClosedAlready();

            try
            {
                TraceSources.Compute.TraceVerbose($"WebSocketStream: begin WriteAsync({count} bytes)... [socket: {this.socket.State}]");
                await this.socket.SendAsync(
                    new ArraySegment <byte>(buffer, offset, count),
                    WebSocketMessageType.Binary,
                    true,
                    cancellationToken).ConfigureAwait(false);

                TraceSources.Compute.TraceVerbose($"WebSocketStream: end WriteAsync()... [socket: {this.socket.State}]");
            }
            catch (Exception e) when(IsSocketError(e, SocketError.ConnectionAborted))
            {
                TraceSources.Compute.TraceVerbose($"WebSocketStream.Send: connection aborted - {e}");

                this.closeByServerReceived = new WebSocketStreamClosedByServerException(
                    WebSocketCloseStatus.NormalClosure,
                    e.Message);

                throw this.closeByServerReceived;
            }
        }
Example #2
0
        protected override async Task <int> ProtectedReadAsync(
            byte[] buffer,
            int offset,
            int count,
            CancellationToken cancellationToken)
        {
            VerifyConnectionNotClosedAlready();

            // Check buffer size. Zero-sized buffers are allowed for
            // connection probing.
            if (count > 0 && count < this.MinReadSize)
            {
                throw new IndexOutOfRangeException($"Read buffer too small, must be at least {this.MinReadSize}");
            }

            try
            {
                int bytesReceived = 0;
                WebSocketReceiveResult result;
                do
                {
                    if (bytesReceived > 0 && bytesReceived == count)
                    {
                        throw new OverflowException("Buffer too small to receive an entire message");
                    }

                    TraceSources.Compute.TraceVerbose($"WebSocketStream: begin ReadAsync()... [socket: {this.socket.State}]");
                    result = await this.socket.ReceiveAsync(
                        new ArraySegment <byte>(
                            buffer,
                            offset + bytesReceived,
                            count - bytesReceived),
                        cancellationToken).ConfigureAwait(false);

                    bytesReceived += result.Count;

                    TraceSources.Compute.TraceVerbose($"WebSocketStream: end ReadAsync() - {result.Count} bytes read [socket: {this.socket.State}]");
                }while (count > 0 && !result.EndOfMessage);

                if (result.CloseStatus != null)
                {
                    Debug.Assert(bytesReceived == 0);

                    TraceSources.Compute.TraceVerbose($"Connection closed by server: {result.CloseStatus}");

                    this.closeByServerReceived = new WebSocketStreamClosedByServerException(
                        result.CloseStatus.Value,
                        result.CloseStatusDescription);

                    // In case of a normal close, it is preferable to simply return 0. But
                    // if the connection was closed abnormally, the client needs to know
                    // the details.
                    if (result.CloseStatus.Value != WebSocketCloseStatus.NormalClosure)
                    {
                        throw this.closeByServerReceived;
                    }
                    else
                    {
                        Debug.Assert(bytesReceived == 0);
                    }
                }

                return(bytesReceived);
            }
            catch (Exception e) when(IsSocketError(e, SocketError.ConnectionAborted))
            {
                TraceSources.Compute.TraceVerbose($"WebSocketStream.Receive: connection aborted - {e}");

                // ClientWebSocket/WinHttp can also throw an exception if
                // the connection has been closed.

                this.closeByServerReceived = new WebSocketStreamClosedByServerException(
                    WebSocketCloseStatus.NormalClosure,
                    e.Message);

                throw this.closeByServerReceived;
            }
        }