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;
        }
Esempio n. 2
0
 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);
            }
        }