void Add(SmtpSession session) { lock (_sessionsLock) { _sessions.Add(session); } }
void Remove(SmtpSession session) { lock (_sessionsLock) { _sessions.Remove(session); } }
/// <summary> /// Listen for SMTP traffic on the given endpoint. /// </summary> /// <param name="endpointDefinition">The definition of the endpoint to listen on.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A task which performs the operation.</returns> private async Task ListenAsync(IEndpointDefinition endpointDefinition, CancellationToken cancellationToken) { var tcpListener = new TcpListener(endpointDefinition.Endpoint); EndPoint localEndPoint = tcpListener.LocalEndpoint; tcpListener.Start(); // keep track of the running tasks for disposal var sessions = new ConcurrentDictionary <SmtpSession, SmtpSession>(); try { OnEndPointStarted(new EndPointEventArgs(endpointDefinition, localEndPoint)); while (cancellationToken.IsCancellationRequested == false) { // wait for a client connection var tcpClient = await tcpListener.AcceptTcpClientAsync().WithCancellation(cancellationToken).ConfigureAwait(false); var networkClient = new NetworkClient(tcpClient.GetStream(), _options.NetworkBufferSize, _options.NetworkBufferReadTimeout); if (endpointDefinition.IsSecure && _options.ServerCertificate != null) { await networkClient.UpgradeAsync(_options.ServerCertificate, _options.SupportedSslProtocols, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); } // create a new session to handle the connection var session = new SmtpSession(_options, tcpClient, networkClient); sessions.TryAdd(session, session); OnSessionCreated(new SessionEventArgs(session.Context)); session.Run(cancellationToken); #pragma warning disable 4014 session.Task .ContinueWith(t => { if (sessions.TryRemove(session, out SmtpSession s)) { s.Dispose(); } OnSessionCompleted(new SessionEventArgs(session.Context)); }, cancellationToken); #pragma warning restore 4014 } // the server has been cancelled, wait for the tasks to complete await Task.WhenAll(sessions.Keys.Select(s => s.Task)).ConfigureAwait(false); } finally { tcpListener.Stop(); OnEndPointStopped(new EndPointEventArgs(endpointDefinition, localEndPoint)); } }
/// <summary> /// Listen for SMTP traffic on the given endpoint. /// </summary> /// <param name="endpointDefinition">The definition of the endpoint to listen on.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A task which performs the operation.</returns> async Task ListenAsync(IEndpointDefinition endpointDefinition, CancellationToken cancellationToken) { // keep track of the running tasks for disposal var sessions = new ConcurrentDictionary <SmtpSession, SmtpSession>(); using (var endpointListener = _options.EndpointListenerFactory.CreateListener(endpointDefinition)) { while (cancellationToken.IsCancellationRequested == false) { var sessionContext = new SmtpSessionContext(_options, endpointDefinition); // wait for a client connection var stream = await endpointListener.GetStreamAsync(sessionContext, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); sessionContext.NetworkClient = new NetworkClient(stream, _options.NetworkBufferSize, _options.NetworkBufferReadTimeout); if (endpointDefinition.IsSecure && _options.ServerCertificate != null) { await sessionContext.NetworkClient.UpgradeAsync(_options.ServerCertificate, _options.SupportedSslProtocols, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); } // create a new session to handle the connection var session = new SmtpSession(sessionContext); sessions.TryAdd(session, session); OnSessionCreated(new SessionEventArgs(sessionContext)); session.Run(cancellationToken); #pragma warning disable 4014 session.Task .ContinueWith(t => { if (sessions.TryRemove(session, out var s)) { sessionContext.NetworkClient.Dispose(); } OnSessionCompleted(new SessionEventArgs(sessionContext)); }, cancellationToken); #pragma warning restore 4014 } // the server has been cancelled, wait for the tasks to complete await Task.WhenAll(sessions.Keys.Select(s => s.Task)).ConfigureAwait(false); } }
/// <summary> /// Listen for SMTP traffic on the given endpoint. /// </summary> /// <param name="endpoint">The endpoint to listen on.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A task which performs the operation.</returns> async Task ListenAsync(IPEndPoint endpoint, CancellationToken cancellationToken) { var tcpListener = new TcpListener(endpoint); tcpListener.Start(); // keep track of the running tasks for disposal var sessions = new ConcurrentDictionary <SmtpSession, SmtpSession>(); try { while (cancellationToken.IsCancellationRequested == false) { // wait for a client connection var tcpClient = await tcpListener.AcceptTcpClientAsync().WithCancellation(cancellationToken).ConfigureAwait(false); // create a new session to handle the connection var session = new SmtpSession(_options, tcpClient); sessions.TryAdd(session, session); OnSessionCreated(new SessionEventArgs(session.Context)); //Start Execute Session session.Run(cancellationToken); #pragma warning disable 4014 session.Task .ContinueWith(t => { if (sessions.TryRemove(session, out SmtpSession s)) { s.Dispose(); } OnSessionCompleted(new SessionEventArgs(session.Context)); }, cancellationToken); #pragma warning restore 4014 } // the server has been cancelled, wait for the tasks to complete await Task.WhenAll(sessions.Keys.Select(s => s.Task)).ConfigureAwait(false); } finally { tcpListener.Stop(); } }
public void Run(SmtpSessionContext sessionContext, CancellationToken cancellationToken) { var session = new SmtpSession(sessionContext); Add(session); _smtpServer.OnSessionCreated(new SessionEventArgs(sessionContext)); session.Run( exception => { Remove(session); sessionContext.NetworkClient.Dispose(); if (exception != null) { _smtpServer.OnSessionFaulted(new SessionFaultedEventArgs(sessionContext, exception)); } _smtpServer.OnSessionCompleted(new SessionEventArgs(sessionContext)); }, cancellationToken); }
public SmtpSessionHandle(SmtpSession session, SmtpSessionContext sessionContext) { Session = session; SessionContext = sessionContext; }