Example #1
0
        private async Task AcceptNewClientAsync(
            TcpClient client,
            ConnectionSetting connectionSettings,
            CancellationToken cancellationToken)
        {
            ILifetimeScope newScope = _scope.BeginLifetimeScope(
                ConnectionScopeTag,
                builder =>
            {
                builder.RegisterInstance(
                    new ConnectionInformation(
                        client.Client.LocalEndPoint.ToString(),
                        client.Client.RemoteEndPoint.ToString()));

                builder.RegisterInstance(new SecurableConnection(client.GetStream(), _keyProvider.GetKey(connectionSettings.Certificate)))
                .As <SecurableConnection>()
                .As <IConnectionSecurity>()
                .As <IVariableStreamReader>();

                builder.RegisterInstance(connectionSettings);

                builder.Register(c => c.ResolveKeyed <IAuthenticationTransport>(connectionSettings.Protocol))
                .As <IAuthenticationTransport>();
            }
                );

            var newSession = newScope.ResolveKeyed <IProtocolSession>(connectionSettings.Protocol);

            using (await SemaphoreLock.GetLockAsync(_sessionSemaphore, cancellationToken))
            {
                _sessions.Add(new SessionHolder(newSession, newSession.RunAsync(cancellationToken), newScope));
            }
        }
Example #2
0
        public async Task RunAsync(CancellationToken cancellationToken)
        {
            _log.Information($"Opening ports: {string.Join(",", _settings.Connections.Select(p => p.Port.ToString()))}");

            TcpListener[] listeners = _settings.Connections
                                      .Select(p => new TcpListener(IPAddress.Any, p.Port))
                                      .ToArray();

            foreach (TcpListener l in listeners)
            {
                l.Start();
            }

            Task <TcpClient>[] listenerTasks = listeners
                                               .Select(tcp => tcp.AcceptTcpClientAsync())
                                               .ToArray();

            while (!cancellationToken.IsCancellationRequested)
            {
                var tasks = new Task[listenerTasks.Length + _sessions.Count];
                Array.Copy(listenerTasks, 0, tasks, 0, listenerTasks.Length);
                _sessions.Select(s => s.Task).ToList().CopyTo(tasks, listenerTasks.Length);

                int  completedIndex = Task.WaitAny(tasks);
                Task task           = tasks[completedIndex];

                if (task is Task <TcpClient> tcpTask)
                {
                    // This is a new connection task
                    TcpClient         client             = tcpTask.Result;
                    ConnectionSetting connectionSettings = _settings.Connections[completedIndex];
                    await AcceptNewClientAsync(client, connectionSettings, cancellationToken);

                    // Wait for another connection
                    listenerTasks[completedIndex] = listeners[completedIndex].AcceptTcpClientAsync();
                }
                else
                {
                    // One of the existing connections is closing
                    using (await SemaphoreLock.GetLockAsync(_sessionSemaphore, cancellationToken))
                    {
                        int           sessionIndex   = completedIndex - listenerTasks.Length;
                        SessionHolder closingSession = _sessions[sessionIndex];
                        _log.Information($"Closing session {closingSession.Session.Id}...");
                        _sessions.RemoveAt(sessionIndex);
                        closingSession.Scope.Dispose();
                    }
                }
            }

            foreach (TcpListener l in listeners)
            {
                l.Stop();
            }
        }