private async Task <WebSocketNegotiationResult> NegotiateWebSocket(Socket client)
        {
            var result = new WebSocketNegotiationResult();

            try
            {
                var timeoutTask = Task.Delay(_options.NegotiationTimeout);
                ConfigureSocket(client);

                Stream stream = new NetworkStream(client, FileAccess.ReadWrite, true);
                foreach (var conExt in ConnectionExtensions)
                {
                    var extTask = conExt.ExtendConnectionAsync(stream);
                    await Task.WhenAny(timeoutTask, extTask).ConfigureAwait(false);

                    if (timeoutTask.IsCompleted)
                    {
                        throw new WebSocketException("Negotiation timeout (Extension: " + conExt.GetType().Name + ")");
                    }

                    stream = await extTask;
                }

                var handshakeTask = _handShaker.HandshakeAsync(stream);
                await Task.WhenAny(timeoutTask, handshakeTask).ConfigureAwait(false);

                if (timeoutTask.IsCompleted)
                {
                    throw new WebSocketException("Negotiation timeout");
                }

                var handshake = await handshakeTask;

                if (handshake.IsValid)
                {
                    result.Result = handshake.Factory.CreateWebSocket(stream, _options, (IPEndPoint)client.LocalEndPoint, (IPEndPoint)client.RemoteEndPoint, handshake.Request, handshake.Response, handshake.NegotiatedMessageExtensions);
                }
                else
                {
                    result.Error = handshake.Error;
                }
            }
            catch (Exception ex)
            {
                FinishSocket(client);
                result.Error  = ExceptionDispatchInfo.Capture(ex);
                result.Result = null;
            }
            return(result);
        }
        private async Task<WebSocketNegotiationResult> NegotiateWebSocket(Socket client)
        {
            var result = new WebSocketNegotiationResult();
            try
            {
                var timeoutTask = Task.Delay(_options.NegotiationTimeout);
                ConfigureSocket(client);

                Stream stream = new NetworkStream(client, FileAccess.ReadWrite, true);
                foreach (var conExt in ConnectionExtensions)
                {
                    var extTask = conExt.ExtendConnectionAsync(stream);
                    await Task.WhenAny(timeoutTask, extTask).ConfigureAwait(false);
                    if (timeoutTask.IsCompleted)
                        throw new WebSocketException("Negotiation timeout (Extension: "+conExt.GetType().Name+")");

                    stream = await extTask;
                }

                var handshakeTask = _handShaker.HandshakeAsync(stream);
                await Task.WhenAny(timeoutTask, handshakeTask).ConfigureAwait(false);
                if (timeoutTask.IsCompleted)
                    throw new WebSocketException("Negotiation timeout");

                var handshake = await handshakeTask;

                if (handshake.IsValid)
                    result.Result = handshake.Factory.CreateWebSocket(stream, _options, (IPEndPoint)client.LocalEndPoint, (IPEndPoint)client.RemoteEndPoint, handshake.Request, handshake.Response, handshake.NegotiatedMessageExtensions);
                else
                    result.Error = handshake.Error;
            }
            catch (Exception ex)
            {
                FinishSocket(client);
                result.Error = ExceptionDispatchInfo.Capture(ex);
                result.Result = null;
            }
            return result;
        }