public override Task SendAsync( ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { _operation.InterlockedCheckValidStates(s_validSendStates); using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken)) { var bufferType = WebSocketMessageTypeAdapter.GetWinHttpMessageType(messageType, endOfMessage); _operation.PinSendBuffer(buffer); bool sendOperationAlreadyPending = false; if (_operation.PendingWriteOperation == false) { lock (_operation.Lock) { _operation.CheckValidState(s_validSendStates); if (_operation.PendingWriteOperation == false) { _operation.PendingWriteOperation = true; _operation.TcsSend = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); uint ret = Interop.WinHttp.WinHttpWebSocketSend( _operation.WebSocketHandle, bufferType, buffer.Count > 0 ? Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array, buffer.Offset) : IntPtr.Zero, (uint)buffer.Count); if (Interop.WinHttp.ERROR_SUCCESS != ret) { throw WinHttpException.CreateExceptionUsingError((int)ret); } } else { sendOperationAlreadyPending = true; } } } else { sendOperationAlreadyPending = true; } if (sendOperationAlreadyPending) { var exception = new InvalidOperationException( SR.Format(SR.net_Websockets_AlreadyOneOutstandingOperation, "SendAsync")); _operation.TcsSend.TrySetException(exception); Abort(); } return(_operation.TcsSend.Task); } }
public override async Task <WebSocketReceiveResult> ReceiveAsync( ArraySegment <byte> buffer, CancellationToken cancellationToken) { _operation.InterlockedCheckValidStates(s_validReceiveStates); using (ThrowOrRegisterCancellation(cancellationToken)) { _operation.PinReceiveBuffer(buffer); await InternalReceiveAsync(buffer).ConfigureAwait(false); // Check for abort. _operation.InterlockedCheckValidStates(s_validAfterReceiveStates); bool endOfMessage; WebSocketMessageType bufferType = WebSocketMessageTypeAdapter.GetWebSocketMessageType(_operation.BufferType, out endOfMessage); int bytesTransferred = checked ((int)_operation.BytesTransferred); WebSocketReceiveResult ret; if (bufferType == WebSocketMessageType.Close) { UpdateServerCloseStatus(); ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage, _closeStatus, _closeStatusDescription); } else { ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage); } return(ret); } }
public override async Task <WebSocketReceiveResult> ReceiveAsync( ArraySegment <byte> buffer, CancellationToken cancellationToken) { _operation.InterlockedCheckValidStates(s_validReceiveStates); using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken)) { // TODO (Issue 2505): replace with PinnableBufferCache. if (!_cachedReceivePinnedBuffer.IsAllocated || _cachedReceivePinnedBuffer.Target != buffer.Array) { if (_cachedReceivePinnedBuffer.IsAllocated) { _cachedReceivePinnedBuffer.Free(); } _cachedReceivePinnedBuffer = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned); } await InternalReceiveAsync(buffer).ConfigureAwait(false); // Check for abort. _operation.InterlockedCheckValidStates(s_validAfterReceiveStates); WebSocketMessageType bufferType; bool endOfMessage; bufferType = WebSocketMessageTypeAdapter.GetWebSocketMessageType(_operation.BufferType, out endOfMessage); int bytesTransferred = 0; checked { bytesTransferred = (int)_operation.BytesTransferred; } WebSocketReceiveResult ret; if (bufferType == WebSocketMessageType.Close) { UpdateServerCloseStatus(); ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage, _closeStatus, _closeStatusDescription); } else { ret = new WebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage); } return(ret); } }
public override async ValueTask <ValueWebSocketReceiveResult> ReceiveAsync(Memory <byte> buffer, CancellationToken cancellationToken) { _operation.InterlockedCheckValidStates(s_validReceiveStates); using (ThrowOrRegisterCancellation(cancellationToken)) using (buffer.Retain(pin: true)) { await InternalReceiveAsync(buffer).ConfigureAwait(false); // Check for abort. _operation.InterlockedCheckValidStates(s_validAfterReceiveStates); WebSocketMessageType bufferType = WebSocketMessageTypeAdapter.GetWebSocketMessageType(_operation.BufferType, out bool endOfMessage); int bytesTransferred = checked ((int)_operation.BytesTransferred); if (bufferType == WebSocketMessageType.Close) { UpdateServerCloseStatus(); } return(new ValueWebSocketReceiveResult(bytesTransferred, bufferType, endOfMessage)); } }
public override Task SendAsync( ArraySegment <byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) { _operation.InterlockedCheckValidStates(s_validSendStates); using (CancellationTokenRegistration ctr = ThrowOrRegisterCancellation(cancellationToken)) { var bufferType = WebSocketMessageTypeAdapter.GetWinHttpMessageType(messageType, endOfMessage); // TODO (Issue 2505): replace with PinnableBufferCache. if (!_cachedSendPinnedBuffer.IsAllocated || _cachedSendPinnedBuffer.Target != buffer.Array) { if (_cachedSendPinnedBuffer.IsAllocated) { _cachedSendPinnedBuffer.Free(); } _cachedSendPinnedBuffer = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned); } bool sendOperationAlreadyPending = false; if (_operation.PendingWriteOperation == false) { lock (_operation.Lock) { _operation.CheckValidState(s_validSendStates); if (_operation.PendingWriteOperation == false) { _operation.PendingWriteOperation = true; _operation.TcsSend = new TaskCompletionSource <bool>(); uint ret = Interop.WinHttp.WinHttpWebSocketSend( _operation.WebSocketHandle, bufferType, buffer.Count > 0 ? Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array, buffer.Offset) : IntPtr.Zero, (uint)buffer.Count); if (Interop.WinHttp.ERROR_SUCCESS != ret) { throw WinHttpException.CreateExceptionUsingError((int)ret); } } else { sendOperationAlreadyPending = true; } } } else { sendOperationAlreadyPending = true; } if (sendOperationAlreadyPending) { var exception = new InvalidOperationException( SR.Format(SR.net_Websockets_AlreadyOneOutstandingOperation, "SendAsync")); _operation.TcsSend.TrySetException(exception); Abort(); } return(_operation.TcsSend.Task); } }