示例#1
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 tcpServerErrorEventArgs = new TcpServerErrorEventArgs(new ErrorData(ex));

                this.OnServerErrorOccured(tcpServerErrorEventArgs);

                return;
            }

            try
            {
                await Task.WhenAll(
                    this.ListenAsync(tcpListener, cancellationToken),
                    Task.Run(() => this.OnServerStarted(new TcpServerStartedEventArgs(new TcpServerStartedData(this.Config.IPAddress, this.Config.Port)))))
                .ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                var tcpServerErrorEventArgs = new TcpServerErrorEventArgs(new ErrorData(ex));

                this.OnServerErrorOccured(tcpServerErrorEventArgs);
            }
            finally
            {
                try
                {
                    tcpListener.Stop();
                }
                catch (Exception ex)
                {
                    var tcpServerErrorEventArgs = new TcpServerErrorEventArgs(new ErrorData(ex));

                    this.OnServerErrorOccured(tcpServerErrorEventArgs);
                }

                this.OnServerStopped(new TcpServerStoppedEventArgs(new TcpServerStoppedData(this.Config.IPAddress, this.Config.Port)));
            }
        }
示例#2
0
 protected virtual void OnServerErrorOccured(TcpServerErrorEventArgs e)
 {
     this.ServerErrorOccured?.Invoke(this, e);
 }
示例#3
0
        // exploiting "async void" simplifies everything
        protected virtual async void HandleNewTcpClientAsync(TcpClient tcpClient, CancellationToken token)
        {
            using (tcpClient)
                using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(token))
                {
                    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 serverErrorEventArgs = new TcpServerErrorEventArgs(new ErrorData(ex));
                        this.OnServerErrorOccured(serverErrorEventArgs);

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

                        return;
                    }
                    catch (Exception)
                    {
                        sendQueue.Complete();
                        return;
                    }

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

                        try
                        {
                            await this.HandleRemotePeerAsync(remoteTcpPeer, linkedCts.Token).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            var unhandledErrorEventArgs = new UnhandledErrorEventArgs(new ErrorData(ex));

                            this.OnUnhandledError(unhandledErrorEventArgs);
                        }
                        finally
                        {
                            sendQueue.Complete();
                            sslStream?.Dispose();
                        }
                    }
                }
        }