public override async Task<WebSocket> CreateWebSocketAsync(Uri address, WebHeaderCollection headers, ICredentials credentials, WebSocketTransportSettings settings, TimeoutHelper timeoutHelper) { ClientWebSocket webSocket = new ClientWebSocket(); webSocket.Options.Credentials = credentials; webSocket.Options.AddSubProtocol(settings.SubProtocol); webSocket.Options.KeepAliveInterval = settings.KeepAliveInterval; foreach (var headerObj in headers) { var header = headerObj as string; webSocket.Options.SetRequestHeader(header, headers[header]); } var cancelToken = await timeoutHelper.GetCancellationTokenAsync(); await webSocket.ConnectAsync(address, cancelToken); return webSocket; }
private async Task<Message> ReadChunkedBufferedMessageAsync(Task<Stream> inputStreamTask, TimeoutHelper timeoutHelper) { try { return await _encoder.ReadMessageAsync(await inputStreamTask, _factory.BufferManager, _factory.MaxBufferSize, _contentType, await timeoutHelper.GetCancellationTokenAsync()); } catch (XmlException xmlException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.MessageXmlProtocolError, xmlException)); } }
public async void WriteEndOfMessageAsync(Action<object> callback, object state) { if (TD.WebSocketAsyncWriteStartIsEnabled()) { // TODO: Open bug about not emitting the hostname/port TD.WebSocketAsyncWriteStart( _webSocket.GetHashCode(), 0, string.Empty); } var timeoutHelper = new TimeoutHelper(_closeTimeout); var cancelTokenTask = timeoutHelper.GetCancellationTokenAsync(); try { var cancelToken = await cancelTokenTask; await _webSocket.SendAsync(new ArraySegment<byte>(Array.Empty<byte>(), 0, 0), _outgoingMessageType, true, cancelToken); if (TD.WebSocketAsyncWriteStopIsEnabled()) { TD.WebSocketAsyncWriteStop(_webSocket.GetHashCode()); } } catch (Exception ex) { if (Fx.IsFatal(ex)) { throw; } if (cancelTokenTask.Result.IsCancellationRequested) { throw Fx.Exception.AsError( new TimeoutException(InternalSR.TaskTimedOutError(timeoutHelper.OriginalTimeout))); } throw WebSocketHelper.ConvertAndTraceException(ex, timeoutHelper.OriginalTimeout, WebSocketHelper.SendOperation); } finally { callback.Invoke(state); } }
async void StartNextReceiveAsync() { Fx.Assert(_receiveTask == null || _receiveTask.Task.IsCompleted, "this.receiveTask is not completed."); _receiveTask = new TaskCompletionSource<object>(); int currentState = Interlocked.CompareExchange(ref _asyncReceiveState, AsyncReceiveState.Started, AsyncReceiveState.Finished); Fx.Assert(currentState == AsyncReceiveState.Finished, "currentState is not AsyncReceiveState.Finished: " + currentState); if (currentState != AsyncReceiveState.Finished) { throw FxTrace.Exception.AsError(new InvalidOperationException()); } try { if (_useStreaming) { if (_streamWaitTask != null) { //// Wait until the previous stream message finished. await _streamWaitTask.Task; } _streamWaitTask = new TaskCompletionSource<object>(); } if (_pendingException == null) { if (!_useStreaming) { await ReadBufferedMessageAsync(); } else { byte[] buffer = _bufferManager.TakeBuffer(_receiveBufferSize); bool success = false; try { if (TD.WebSocketAsyncReadStartIsEnabled()) { TD.WebSocketAsyncReadStart(_webSocket.GetHashCode()); } try { WebSocketReceiveResult result; TimeoutHelper helper = new TimeoutHelper(_asyncReceiveTimeout); var cancelToken = await helper.GetCancellationTokenAsync(); result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, 0, _receiveBufferSize), cancelToken); CheckCloseStatus(result); _pendingMessage = PrepareMessage(result, buffer, result.Count); if (TD.WebSocketAsyncReadStopIsEnabled()) { TD.WebSocketAsyncReadStop( _webSocket.GetHashCode(), result.Count, String.Empty); } } catch (AggregateException ex) { WebSocketHelper.ThrowCorrectException(ex, _asyncReceiveTimeout, WebSocketHelper.ReceiveOperation); } success = true; } catch (Exception ex) { if (Fx.IsFatal(ex)) { throw; } _pendingException = WebSocketHelper.ConvertAndTraceException(ex, _asyncReceiveTimeout, WebSocketHelper.ReceiveOperation); } finally { if (!success) { _bufferManager.ReturnBuffer(buffer); } } } } } finally { if (Interlocked.CompareExchange(ref _asyncReceiveState, AsyncReceiveState.Finished, AsyncReceiveState.Started) == AsyncReceiveState.Started) { _receiveTask.SetResult(null); } } }
protected override async Task CloseOutputSessionCoreAsync(TimeSpan timeout) { if (TD.WebSocketCloseOutputSentIsEnabled()) { TD.WebSocketCloseOutputSent( WebSocket.GetHashCode(), _webSocketCloseDetails.OutputCloseStatus.ToString(), RemoteAddress != null ? RemoteAddress.ToString() : string.Empty); } var helper = new TimeoutHelper(timeout); var cancelToken = await helper.GetCancellationTokenAsync(); try { await CloseOutputAsync(cancelToken); } catch (Exception ex) { if (Fx.IsFatal(ex)) { throw; } if (cancelToken.IsCancellationRequested) { throw Fx.Exception.AsError(new TimeoutException(InternalSR.TaskTimedOutError(timeout))); } throw WebSocketHelper.ConvertAndTraceException(ex, timeout, WebSocketHelper.ReceiveOperation); } }