Example #1
0
 protected virtual void OnServerExceptionOccured(TcpServerExceptionEventArgs e)
 {
     try
     {
         this.ServerExceptionOccured?.Invoke(this, e);
     }
     catch (Exception ex)
     {
         var ue = new ExceptionEventArgs(ex);
         this.OnUnhandledException(ue);
     }
 }
Example #2
0
        /// <summary>
        /// Asynchronously starts the server that will run until <paramref name="cancellationToken" /> is cancelled
        /// </summary>
        /// <param name="cancellationToken">Cancellation token</param>
        /// <returns><see cref="Task" /></returns>
        public virtual async Task StartAsync(CancellationToken cancellationToken)
        {
            var tcpListener = this.CreateTcpListener();

            this.Config.ConfigureTcpListenerCallback?.Invoke(tcpListener);

            try
            {
                tcpListener.Start();
            }
            catch (Exception ex)
            {
                var e = new TcpServerExceptionEventArgs(ex);

                this.OnServerExceptionOccured(e);

                return;
            }

            try
            {
                await Task.WhenAll(
                    this.ListenAsync(tcpListener, cancellationToken),
                    Task.Run(() => this.OnServerStarted(new TcpServerStartedEventArgs()
                {
                    ServerAddress = this.Config.IPAddress,
                    ServerPort    = this.Config.Port
                })))
                .ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                var e = new TcpServerExceptionEventArgs(ex);

                this.OnServerExceptionOccured(e);
            }
            finally
            {
                try
                {
                    tcpListener.Stop();
                }
                catch (Exception ex)
                {
                    var e = new TcpServerExceptionEventArgs(ex);

                    this.OnServerExceptionOccured(e);
                }

                this.OnServerStopped(new TcpServerStoppedEventArgs());
            }
        }
Example #3
0
        // exploiting "async void" simplifies everything
        protected virtual async void HandleNewTcpClientAsync(TcpClient tcpClient, CancellationToken token)
        {
            try
            {
                await this.HandleNewTcpClientTask(tcpClient, token).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                var se = new TcpServerExceptionEventArgs(ex);

                this.OnServerExceptionOccured(se);
            }
        }
Example #4
0
        protected virtual async Task HandleNewTcpClientTask(TcpClient tcpClient, CancellationToken token)
        {
            using (tcpClient)
            {
                var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(token); // remote tcp peer controls linkedCts lifetime
                var sendQueue = this.CreateSendQueueActionBlock(linkedCts.Token);

                RemoteTcpPeer remoteTcpPeer;
                SslStream     sslStream = null;

                try
                {
                    if (this.Config.UseSsl && this.Config.X509Certificate != null)
                    {
                        sslStream = this.CreateSslStream(tcpClient);

                        await this.AuthenticateSslStream(tcpClient, sslStream, linkedCts.Token)
                        .ConfigureAwait(false);

                        remoteTcpPeer = this.CreateRemoteTcpPeer(tcpClient, sslStream, sendQueue, linkedCts);
                    }
                    else
                    {
                        remoteTcpPeer = this.CreateRemoteTcpPeer(tcpClient, sendQueue, linkedCts);
                    }
                }
                catch (AuthenticationException ex)
                {
                    var e = new TcpServerExceptionEventArgs(ex);
                    this.OnServerExceptionOccured(e);

                    sendQueue.Complete();
                    sslStream?.Dispose();
                    linkedCts.Dispose();

                    return;
                }
                catch (Exception ex)
                {
                    var e = new TcpServerExceptionEventArgs(ex);
                    this.OnServerExceptionOccured(e);

                    sendQueue.Complete();
                    linkedCts.Dispose();
                    return;
                }

                using (remoteTcpPeer)
                {
                    this.AddRemoteTcpPeerToConnectedList(remoteTcpPeer);

                    var connectionEstablishedEventArgs = new ConnectionEstablishedEventArgs(remoteTcpPeer);
                    this.OnConnectionEstablished(connectionEstablishedEventArgs);

                    await this.HandleRemotePeerAsync(remoteTcpPeer, linkedCts.Token).ConfigureAwait(false);

                    sendQueue.Complete();
                    sslStream?.Dispose();
                }
            }
        }