Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enables the underlying TCP Listener to be configured and run by the c… #115

Closed

Conversation

robeving
Copy link

@robeving robeving commented Dec 1, 2020

This PR enables the caller to have greater control of the underlying TCPListener implementation by specifying an interface to use. It also makes PausableFtpService public. PausableFtpService is used by a number of classes already and it does a lot of the heavy lifting so callers should make use of it.

In my case I have my own server implementation that I want to use which provides diagnostics, management etc. I can now use a very small class like this to pass through individual TCP connections.

    internal class InternalListener : PausableFtpService, IListenerService
    {
        private readonly Channel<TcpClient> channels = System.Threading.Channels.Channel.CreateBounded<TcpClient>(1);
        private CancellationTokenSource cts;
        private TcpClient client;

        public InternalListener(CancellationTokenSource cts, TcpClient client) : base(cts.Token)
        {
            this.cts = cts;
            this.client = client;
        }

        public ChannelReader<TcpClient> Channel => channels;
        public CancellationToken Token => cts.Token;
        public bool IsCancellationRequested => cts.IsCancellationRequested;
        public event EventHandler<ListenerStartedEventArgs> ListenerStarted;

        public void Cancel(bool throwOnFirstException)
        {
            cts.Cancel(throwOnFirstException);
        }

        public void Dispose()
        {
            cts.Cancel();
            cts.Dispose();
        }

        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            try
            {
                ListenerStarted?.Invoke(this, new ListenerStartedEventArgs((client.Client.LocalEndPoint as IPEndPoint).Port));
                await channels.Writer.WriteAsync(client, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex) when (ex is OperationCanceledException)
            {
                // Ignore - everything is fine
            }
        }
    }

Fixes #114

@fubar-coder
Copy link
Contributor

This looks good. I'll take a look why some of the checks failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pass an 'FtpServerListenerService' in via the constructor
2 participants