public async Task <bool> ReuseConnectionAsync(FramingConnection connection, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(false);
            }

            if (!_connectionPoolSemaphore.Wait(0))
            {
                //if (DiagnosticUtility.ShouldTraceWarning)
                //{
                //    TraceUtility.TraceEvent(TraceEventType.Warning,
                //        TraceCode.ServerMaxPooledConnectionsQuotaReached,
                //        SR.GetString(SR.TraceCodeServerMaxPooledConnectionsQuotaReached, maxPooledConnections),
                //        new StringTraceRecord("MaxOutboundConnectionsPerEndpoint", maxPooledConnections.ToString(CultureInfo.InvariantCulture)),
                //        this, null);
                //}

                //if (TD.ServerMaxPooledConnectionsQuotaReachedIsEnabled())
                //{
                //    TD.ServerMaxPooledConnectionsQuotaReached();
                //}

                // No space left in the connection pool
                return(false);
            }

            try
            {
                connection.Reset();

                var ct = new TimeoutHelper(_idleTimeout).GetCancellationToken();
                using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
                           new TimeoutHelper(_idleTimeout).GetCancellationToken(),
                           cancellationToken))
                {
                    var readResult = await connection.Input.ReadAsync(linkedCts.Token);

                    connection.Input.AdvanceTo(readResult.Buffer.Start); // Don't consume any bytes. The pending read is to know when a new client connects.
                    if (readResult.Buffer.IsEmpty && !readResult.IsCompleted && !readResult.IsCanceled)
                    {
                        // After pending read is canceled, next ReadAsync can return immediately with a 0 byte response so another ReadAsync call is needed
                        readResult = await connection.Input.ReadAsync(linkedCts.Token);

                        connection.Input.AdvanceTo(readResult.Buffer.Start); // Don't consume any bytes. The pending read is to know when a new client connects.
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
            finally
            {
                _connectionPoolSemaphore.Release();
            }
        }
 public ServerFramingDuplexSessionChannel(FramingConnection connection, ITransportFactorySettings settings,
                                          bool exposeConnectionProperty, IServiceProvider serviceProvider)
     : base(connection, settings, exposeConnectionProperty)
 {
     Connection       = connection;
     _serviceProvider = serviceProvider;
     SetMessageSource(new ServerSessionConnectionMessageSource(connection));
 }
示例#3
0
 public ServerFramingDuplexSessionChannel(FramingConnection connection, ITransportFactorySettings settings,
                                          bool exposeConnectionProperty, IServiceProvider serviceProvider)
     : base(connection, settings, exposeConnectionProperty)
 {
     Connection       = connection;
     upgradeAcceptor  = connection.StreamUpgradeAcceptor;
     _serviceProvider = serviceProvider;
     //if (upgradeAcceptor != null)
     //{
     //    this.channelBindingProvider = upgrade.GetProperty<IStreamUpgradeChannelBindingProvider>();
     //    this.upgradeAcceptor = upgrade.CreateUpgradeAcceptor();
     //}
 }
示例#4
0
        /// <summary>
        /// Executes the middleware.
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
        /// <returns>A task that represents the execution of this middleware.</returns>
        public async Task Invoke(FramingConnection connection)
        {
            if (connection == null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            if (_options.Predicate(connection))
            {
                await _options.Branch(connection);
            }
            else
            {
                await _next(connection);
            }
        }
示例#5
0
 protected FramingDuplexSessionChannel(FramingConnection connection, ITransportFactorySettings settings, bool exposeConnectionProperty)
     : this(settings, new EndpointAddress(connection.ServiceDispatcher.BaseAddress), connection.Via,
            EndpointAddress.AnonymousAddress, connection.MessageEncoder.MessageVersion.Addressing.AnonymousUri, exposeConnectionProperty)
 {
     Session = FramingConnectionDuplexSession.CreateSession(this, connection.StreamUpgradeAcceptor);
 }
示例#6
0
 public ServerSessionConnectionMessageSource(FramingConnection connection)
 {
     _connection = connection;
 }
示例#7
0
        public async Task <bool> ReuseConnectionAsync(FramingConnection connection, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(false);
            }

            if (!_connectionPoolSemaphore.Wait(0))
            {
                //if (DiagnosticUtility.ShouldTraceWarning)
                //{
                //    TraceUtility.TraceEvent(TraceEventType.Warning,
                //        TraceCode.ServerMaxPooledConnectionsQuotaReached,
                //        SR.GetString(SR.TraceCodeServerMaxPooledConnectionsQuotaReached, maxPooledConnections),
                //        new StringTraceRecord("MaxOutboundConnectionsPerEndpoint", maxPooledConnections.ToString(CultureInfo.InvariantCulture)),
                //        this, null);
                //}

                //if (TD.ServerMaxPooledConnectionsQuotaReachedIsEnabled())
                //{
                //    TD.ServerMaxPooledConnectionsQuotaReached();
                //}
                connection.Logger.ConnectionPoolFull();
                // No space left in the connection pool
                return(false);
            }

            try
            {
                connection.Reset();

                CancellationToken ct = new TimeoutHelper(_idleTimeout).GetCancellationToken();
                using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
                           new TimeoutHelper(_idleTimeout).GetCancellationToken(),
                           cancellationToken))
                {
                    connection.Logger.StartPendingReadOnIdleSocket();
                    Debug.Assert(connection.Transport == connection.RawTransport);
                    var readResult = await connection.Input.ReadAsync(linkedCts.Token);

                    connection.Logger.EndPendingReadOnIdleSocket(readResult);
                    if (readResult.IsCompleted)
                    {
                        connection.Logger.IdleConnectionClosed();
                        connection.Output.Complete();
                        return(false);
                    }

                    connection.Input.AdvanceTo(readResult.Buffer.Start); // Don't consume any bytes. The pending read is to know when a new client connects.
                }

                return(true);
            }
            catch (Exception e)
            {
                connection.Logger.FailureInConnectionReuse(e);
                return(false);
            }
            finally
            {
                _connectionPoolSemaphore.Release();
            }
        }