|
2 | 2 | // Copyright (c) Fubar Development Junker. All rights reserved. |
3 | 3 | // </copyright> |
4 | 4 |
|
5 | | -using System.Collections.Immutable; |
6 | 5 | using System.Net; |
7 | 6 | using System.Threading.Channels; |
8 | 7 |
|
9 | | -using FubarDev.FtpServer.Abstractions; |
10 | | - |
11 | 8 | using Microsoft.AspNetCore.Connections; |
12 | 9 | using Microsoft.Extensions.Options; |
13 | 10 |
|
14 | | -namespace FtpServerRestart01; |
| 11 | +namespace FtpServer; |
15 | 12 |
|
16 | 13 | public class FtpServerService : BackgroundService |
17 | 14 | { |
18 | | - private readonly object _activeClientsLock = new(); |
19 | | - private readonly IFtpClientFactory _clientFactory; |
20 | 15 | private readonly Channel<ConnectionContext> _connectionContextChannel; |
21 | 16 | private readonly IConnectionListenerFactory _connectionListenerFactory; |
| 17 | + private readonly IFtpClientManager _clientManager; |
22 | 18 | private readonly ILogger<FtpServerService> _logger; |
23 | 19 | private readonly FtpServerOptions _serverOptions; |
24 | | - private volatile ImmutableList<FtpClientInformation> _activeClients = ImmutableList<FtpClientInformation>.Empty; |
25 | 20 |
|
26 | 21 | public FtpServerService( |
27 | 22 | IOptions<FtpServerOptions> serverOptions, |
28 | 23 | IConnectionListenerFactory connectionListenerFactory, |
29 | | - IFtpClientFactory clientFactory, |
| 24 | + IFtpClientManager clientManager, |
30 | 25 | ILogger<FtpServerService> logger) |
31 | 26 | { |
32 | 27 | _connectionListenerFactory = connectionListenerFactory; |
33 | | - _clientFactory = clientFactory; |
| 28 | + _clientManager = clientManager; |
34 | 29 | _logger = logger; |
35 | 30 | _serverOptions = serverOptions.Value; |
36 | 31 | _connectionContextChannel = Channel.CreateUnbounded<ConnectionContext>(); |
@@ -65,9 +60,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) |
65 | 60 | while (!stoppingToken.IsCancellationRequested) |
66 | 61 | { |
67 | 62 | var connectionContext = await _connectionContextChannel.Reader.ReadAsync(stoppingToken); |
68 | | - _ = Task.Run( |
69 | | - () => ExecuteClientAsync(connectionContext, stoppingToken), |
70 | | - CancellationToken.None); |
| 63 | + await _clientManager.StartAsync(connectionContext, stoppingToken); |
71 | 64 | } |
72 | 65 | } |
73 | 66 | catch (OperationCanceledException) |
@@ -116,34 +109,4 @@ private static IAsyncEnumerable<IPEndPoint> GetListenEndPointsAsync( |
116 | 109 |
|
117 | 110 | return options.ListenEndPoints.ToAsyncEnumerable(); |
118 | 111 | } |
119 | | - |
120 | | - private async Task ExecuteClientAsync( |
121 | | - ConnectionContext connectionContext, |
122 | | - CancellationToken cancellationToken) |
123 | | - { |
124 | | - await using var registration = cancellationToken.Register( |
125 | | - connectionContext.Abort); |
126 | | - try |
127 | | - { |
128 | | - var client = await _clientFactory.CreateClientAsync(connectionContext, cancellationToken); |
129 | | - var clientInfo = new FtpClientInformation(client, connectionContext); |
130 | | - lock (_activeClientsLock) |
131 | | - { |
132 | | - _activeClients = _activeClients.Add(clientInfo); |
133 | | - } |
134 | | - |
135 | | - _logger.LogTrace("FTP client added"); |
136 | | - await client.RunAsync(connectionContext.ConnectionClosed); |
137 | | - |
138 | | - lock (_activeClientsLock) |
139 | | - { |
140 | | - _activeClients = _activeClients.Remove(clientInfo); |
141 | | - _logger.LogTrace("FTP client removed"); |
142 | | - } |
143 | | - } |
144 | | - finally |
145 | | - { |
146 | | - await connectionContext.DisposeAsync(); |
147 | | - } |
148 | | - } |
149 | 112 | } |
0 commit comments