Code Examples

Real-world code examples ready to use. Copy, paste, and customize according to your needs.

16
Code Examples
3
Difficulty Levels
25+
Features
100%
Tested

Basic

A simple SMTP server in its most basic form

Beginner
BasicExample.cs
using Zetian.Server;

// Basic SMTP server - accepts all messages
using var server = new SmtpServerBuilder()
    .Port(25)
    .ServerName("My SMTP Server")
    .MaxMessageSizeMB(10)
    .Build();

server.MessageReceived += async (sender, e) => {
    Console.WriteLine($"New message from {e.Message.From}");
    Console.WriteLine($"Subject: {e.Message.Subject}");
    
    // Save message to file
    var fileName = $"message_{e.Message.Id}.eml";
    await e.Message.SaveToFileAsync(fileName);
};

await server.StartAsync();
Console.WriteLine("SMTP Server is running on port 25");
Async/AwaitEvent-DrivenProduction Ready

Authenticated

Secure server with username and password

Intermediate
AuthenticatedExample.cs
using Zetian.Models;
using Zetian.Server;

// Authenticated SMTP server
using var server = new SmtpServerBuilder()
    .Port(587)
    .RequireAuthentication()
    .AllowPlainTextAuthentication() // For testing without TLS
    .AuthenticationHandler(async (username, password) =>
    {
        // Example: Check hardcoded credentials
        if (username == "testuser" && password == "testpass")
        {
            return AuthenticationResult.Succeed(username);
        }
        
        // In production, validate against a database:
        // if (await CheckDatabase(username, password))
        //     return AuthenticationResult.Succeed(username);
        
        return AuthenticationResult.Fail();
    })
    .AddAuthenticationMechanism("PLAIN")
    .AddAuthenticationMechanism("LOGIN")
    .Build();

server.MessageReceived += (sender, e) => {
    if (e.Session.IsAuthenticated)
    {
        Console.WriteLine($"User {e.Session.AuthenticatedIdentity} sent message");
        Console.WriteLine($"Subject: {e.Message.Subject}");
    }
};

await server.StartAsync();
Console.WriteLine("SMTP Server with authentication on port 587");
Async/AwaitEvent-DrivenProduction Ready

Secure

Encrypted connections with STARTTLS

Intermediate
SecureExample.cs
using Zetian.Server;

// Secure SMTP server with TLS/SSL support
using var server = new SmtpServerBuilder()
    .Port(587)
    .Certificate("certificate.pfx", "password")
    .RequireSecureConnection()
    .RequireAuthentication()
    .SimpleAuthentication("admin", "admin123")
    .Build();

server.SessionCreated += (sender, e) => {
    Console.WriteLine($"New {(e.Session.IsSecure ? "SECURE" : "INSECURE")} connection");
    Console.WriteLine($"  From: {e.Session.RemoteEndPoint}");
};

server.MessageReceived += (sender, e) => {
    if (e.Session.IsSecure)
    {
        Console.WriteLine("Message received over secure connection");
    }
};

await server.StartAsync();
Console.WriteLine("Secure SMTP Server running with STARTTLS support on port 587");
Async/AwaitEvent-DrivenProduction Ready

Redis Storage

High-performance in-memory storage with Redis

Intermediate
RedisStorageExample.cs
using Zetian.Server;
using Zetian.Storage.Redis.Extensions;

// SMTP server with Redis storage backend
using var server = new SmtpServerBuilder()
    .Port(25)
    .WithRedisStorage("localhost:6379")  // Use Redis for message storage
    .Build();

// Configure Redis with advanced options
// using var server = new SmtpServerBuilder()
//     .Port(25)
//     .WithRedisStorage("localhost:6379", config =>
//     {
//         config.DatabaseNumber = 0;
//         config.KeyPrefix = "smtp:";
//         config.MessageTTLSeconds = 1440;  // 24 hours
//         config.MaxMessageSizeMB = 10;
//         config.CompressMessageBody = true;
//     })
//     .Build();

server.MessageReceived += async (sender, e) => {
    Console.WriteLine($"Message {e.Message.Id} stored in Redis");
    Console.WriteLine($"From: {e.Message.From?.Address}");
    Console.WriteLine($"To: {string.Join(", ", e.Message.Recipients.Select(r => r.Address))}");
    
    // Message is automatically stored in Redis
    // Retrieve later using: await redis.GetMessage(messageId);
};

await server.StartAsync();
Console.WriteLine("SMTP Server with Redis storage on port 25");
Async/AwaitEvent-DrivenProduction Ready

MongoDB Storage

NoSQL document storage with MongoDB

Intermediate
MongoDBStorageExample.cs
using Zetian.Server;
using Zetian.Storage.MongoDB.Extensions;

// SMTP server with MongoDB storage
using var server = new SmtpServerBuilder()
    .Port(25)
    .WithMongoDbStorage(
        connectionString: "mongodb://localhost:27017",
        databaseName: "smtp_server",
        collection: "messages")
    .Build();

// Advanced MongoDB configuration
// using var server = new SmtpServerBuilder()
//     .Port(25)
//     .WithMongoDbStorage("mongodb://localhost:27017", "email_system", config =>
//     {
//         config.CollectionName = "emails";
//         config.UseGridFsForLargeMessages = true;  // For large attachments
//         config.AutoCreateIndexes = true;
//         config.TTLDays = 30;  // Auto-delete after 30 days
//     })
//     .Build();

server.MessageReceived += async (sender, e) => {
    var message = e.Message;
    
    Console.WriteLine($"Message saved to MongoDB");
    Console.WriteLine($"  ID: {message.Id}");
    Console.WriteLine($"  Subject: {message.Subject}");
    Console.WriteLine($"  Attachments: {message.AttachmentCount}");
    
    // GridFS handles large attachments automatically
    // TTL index ensures old messages are cleaned up
};

await server.StartAsync();
Console.WriteLine("SMTP Server with MongoDB storage running on port 25");
Async/AwaitEvent-DrivenProduction Ready

SQL Server Storage

Enterprise-grade storage with SQL Server

Intermediate
SQLServerStorageExample.cs
using Zetian.Server;
using Zetian.Storage.SqlServer.Extensions;

// SMTP server with SQL Server storage
using var server = new SmtpServerBuilder()
    .Port(25)
    .WithSqlServerStorage(
        "Server=localhost;Database=SmtpDb;Trusted_Connection=true;")
    .Build();

// Advanced SQL Server configuration
// using var server = new SmtpServerBuilder()
//     .Port(25)
//     .WithSqlServerStorage(connectionString, config =>
//     {
//         config.TableName = "EmailMessages";
//         config.SchemaName = "smtp";
//         config.AutoCreateTable = true;
//         config.CompressMessageBody = true;
//     })
//     .Build();

server.MessageReceived += async (sender, e) => {
    Console.WriteLine($"Message stored in SQL Server");
    Console.WriteLine($"  Table: smtp.EmailMessages");
    Console.WriteLine($"  Compression: Enabled");
    
    // Full-text search available:
    // SELECT * FROM smtp.EmailMessages 
    // WHERE CONTAINS(Subject, 'important')
};

await server.StartAsync();
Console.WriteLine("SMTP Server with SQL Server storage on port 25");
Async/AwaitEvent-DrivenProduction Ready

Multi-Provider Storage

Multiple storage backends with failover

Advanced
Multi-ProviderStorageExample.cs
using Zetian.Server;
using Zetian.Storage.Redis.Extensions;
using Zetian.Storage.SqlServer.Extensions;
using Zetian.Storage.AzureBlob.Extensions;

// SMTP server with multiple storage providers
using var server = new SmtpServerBuilder()
    .Port(25)
    // Primary storage: Fast Redis cache
    .WithRedisStorage("localhost:6379", config =>
    {
        config.MessageTTLSeconds = 60;  // Short-term cache
    })
    // Secondary storage: SQL Server for search
    .WithSqlServerStorage(
        "Server=localhost;Database=SmtpDb;Trusted_Connection=true;",
        config => 
        {
            config.AutoCreateTable = true;
            config.StoreAttachmentsSeparately = false;
        })
    // Archive storage: Azure Blob for long-term
    .WithAzureBlobStorage(
        "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;",
        config =>
        {
            config.ContainerName = "email-archive";
            config.AccessTier = BlobAccessTier.Cool;
        })
    .Build();

server.MessageReceived += async (sender, e) => {
    var message = e.Message;
    
    Console.WriteLine("Message stored in multiple backends:");
    Console.WriteLine("  ✓ Redis (hot cache) - Instant access");
    Console.WriteLine("  ✓ SQL Server - Full-text searchable");
    Console.WriteLine("  ✓ Azure Blob - Long-term archive");
    
    // Automatic tiering:
    // - Last 1 hour: Served from Redis
    // - Last 30 days: Served from SQL Server
    // - Older: Retrieved from Azure Blob
};

// Failover is automatic
server.ErrorOccurred += (sender, e) => {
    if (e.Exception.Message.Contains("Redis"))
    {
        Console.WriteLine("Redis unavailable, falling back to SQL Server");
    }
};

await server.StartAsync();
Console.WriteLine("Multi-provider SMTP server with automatic failover");
Async/AwaitEvent-DrivenProduction Ready

Amazon S3 Storage

Cloud storage with S3 or compatible services

Intermediate
AmazonS3StorageExample.cs
using Zetian.Server;
using Zetian.Storage.AmazonS3.Extensions;

// SMTP server with Amazon S3 storage
using var server = new SmtpServerBuilder()
    .Port(25)
    .WithS3Storage(
        accessKeyId: Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID"),
        secretAccessKey: Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY"),
        bucketName: "smtp-messages", config =>
        {
            config.Region = "us-west-2";
        })
    .Build();

// Advanced S3 configuration with encryption and lifecycle
// using var server = new SmtpServerBuilder()
//     .Port(25)
//     .WithS3Storage(accessKeyId, secretAccessKey, bucketName, config =>
//     {
//         config.Region = "us-west-2";
//         config.KeyPrefix = "emails/";
//         
//         // Server-side encryption
//         config.EnableServerSideEncryption = true;
//         config.KmsKeyId = "alias/my-kms-key";
//         
//         // Lifecycle rules
//         config.TransitionToIADays = 7;
//         config.TransitionToGlacierDays = 90;
//     })
//     .Build();

server.MessageReceived += async (sender, e) => {
    Console.WriteLine($"Message uploaded to S3");
    Console.WriteLine($"  Bucket: smtp-messages");
    Console.WriteLine($"  Region: us-west-2");
    Console.WriteLine($"  Encryption: AES-256");
    
    // Cost optimization with automatic tiering:
    // - Standard: First 30 days
    // - Infrequent Access: 30-90 days  
    // - Glacier: After 90 days
};

await server.StartAsync();
Console.WriteLine("SMTP Server with S3 storage on port 25");
Async/AwaitEvent-DrivenProduction Ready

Azure Blob Storage

Scalable cloud storage with Azure

Intermediate
AzureBlobStorageExample.cs
using Zetian.Server;
using Zetian.Storage.AzureBlob.Extensions;

// SMTP server with Azure Blob storage
using var server = new SmtpServerBuilder()
    .Port(25)
    .WithAzureBlobStorage(
        "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey;")
    .Build();

// Advanced Azure Blob configuration
// using var server = new SmtpServerBuilder()
//     .Port(25)
//     .WithAzureBlobStorage(connectionString, config =>
//     {
//         config.ContainerName = "smtp-messages";
//         
//         // Access tiers for cost optimization
//         config.AccessTier = BlobAccessTier.Cool;
//         
//         // Security features
//         config.EnableSoftDelete = true;
//         config.SoftDeleteRetentionDays = 7;
//         config.CompressMessageBody = true;
//         
//         // Azure AD authentication (instead of connection string)
//         // config.UseAzureAdAuthentication = true;
//     })
//     .Build();

server.MessageReceived += async (sender, e) => {
    Console.WriteLine($"Message stored in Azure Blob Storage");
    Console.WriteLine($"  Container: smtp-messages");
    Console.WriteLine($"  Access Tier: Cool");
    Console.WriteLine($"  Encryption: Enabled");
    
    // Automatic lifecycle management:
    // - Cool tier: Default for cost savings
    // - Archive tier: After 30 days
    // - Soft delete: 7 days retention
};

await server.StartAsync();
Console.WriteLine("SMTP Server with Azure Blob storage on port 25");
Async/AwaitEvent-DrivenProduction Ready

PostgreSQL Storage

Advanced JSON storage with PostgreSQL

Intermediate
PostgreSQLStorageExample.cs
using Zetian.Server;
using Zetian.Storage.PostgreSQL.Extensions;

// SMTP server with PostgreSQL storage
using var server = new SmtpServerBuilder()
    .Port(25)
    .WithPostgreSqlStorage(
        "Host=localhost;Database=smtp_db;Username=postgres;Password=postgres")
    .Build();

// Advanced PostgreSQL with partitioning and JSONB
// using var server = new SmtpServerBuilder()
//     .Port(25)
//     .WithPostgreSqlStorage(connectionString, config =>
//     {
//         config.TableName = "email_messages";
//         config.SchemaName = "smtp";
//         config.AutoCreateTable = true;
//         
//         // JSONB for headers and metadata
//         config.UseJsonbForHeaders = true;
//         config.CreateIndexes = true;  // Fast JSON queries
//         
//         // Table partitioning for scale
//         config.EnablePartitioning = true;
//         config.PartitionInterval = PartitionInterval.Monthly;
//     })
//     .Build();

server.MessageReceived += async (sender, e) => {
    Console.WriteLine($"Message stored in PostgreSQL");
    Console.WriteLine($"  JSONB storage for flexible queries");
    Console.WriteLine($"  GIN indexed for fast searches");
    
    // Example JSONB queries:
    // SELECT * FROM smtp.email_messages 
    // WHERE headers @> '{"X-Spam-Score": "0"}'
    // 
    // Full text search:
    // WHERE to_tsvector('english', body) @@ plainto_tsquery('important')
};

await server.StartAsync();
Console.WriteLine("SMTP Server with PostgreSQL storage on port 25");
Async/AwaitEvent-DrivenProduction Ready

Rate Limited

Speed limiting for spam protection

Intermediate
RateLimitedExample.cs
using Zetian.Models;
using Zetian.Server;
using Zetian.Extensions;

// SMTP server protected with rate limiting
using var server = new SmtpServerBuilder()
    .Port(25)
    .MaxConnections(100)
    .MaxConnectionsPerIP(5)
    .Build();

// Add rate limiting - 100 messages per hour per IP
server.AddRateLimiting(RateLimitConfiguration.PerHour(100));

// Alternative configurations:
// server.AddRateLimiting(RateLimitConfiguration.PerMinute(10));
// server.AddRateLimiting(RateLimitConfiguration.PerDay(1000));

server.MessageReceived += (sender, e) => {
    Console.WriteLine($"Message from {e.Session.RemoteEndPoint}");
    // Rate limiting is handled automatically
    // Messages exceeding limit get SMTP error 421
};

server.ErrorOccurred += (sender, e) => {
    if (e.Exception.Message.Contains("rate limit"))
        Console.WriteLine($"Rate limit exceeded: {e.Session?.RemoteEndPoint}");
};

await server.StartAsync();
Console.WriteLine("Rate-limited server on port 25");
Async/AwaitEvent-DrivenProduction Ready

Custom Processing

Domain and content-based filtering

Advanced
CustomProcessingExample.cs
using Zetian.Server;
using Zetian.Protocol;

// Protocol-level filtering
using var server = new SmtpServerBuilder()
    .Port(25)
    // Only accept messages from these domains
    .WithSenderDomainWhitelist("trusted.com", "partner.org")
    // Block these domains
    .WithSenderDomainBlacklist("spam.com", "junk.org")
    // Only accept messages to these domains
    .WithRecipientDomainWhitelist("mydomain.com", "mycompany.com")
    .Build();

// Event-based filtering
server.MessageReceived += (sender, e) => {
    var message = e.Message;
    
    // Check for spam words
    var spamWords = new[] { "viagra", "lottery", "winner" };
    if (spamWords.Any(word => message.Subject?.Contains(word, StringComparison.OrdinalIgnoreCase) ?? false))
    {
        e.Cancel = true;
        e.Response = new SmtpResponse(550, "Message rejected: Spam detected");
        return;
    }
    
    // Check message size
    if (message.Size > 10_000_000) // 10MB
    {
        e.Cancel = true;
        e.Response = new SmtpResponse(552, "Message too large");
        return;
    }
    
    Console.WriteLine("Message passed all filters");
};

await server.StartAsync();
Async/AwaitEvent-DrivenProduction Ready

Message Storage

Saving messages to file system or database

Advanced
MessageStorageExample.cs
using System.Net;
using Zetian.Server;
using System.Text.Json;
using Zetian.Abstractions;

// SMTP server with built-in file storage
using var server = new SmtpServerBuilder()
    .Port(25)
    // Save messages to file system automatically
    .WithFileMessageStore(@"C:\smtp_messages", createDateFolders: true)
    .Build();

// Using custom message store
// var customStore = new JsonMessageStore(@"C:\email_storage");
// var server = new SmtpServerBuilder()
//     .Port(25)
//     .MessageStore(customStore)
//     .Build();

// Log when messages are received and stored
server.MessageReceived += (sender, e) => {
    Console.WriteLine($"Message {e.Message.Id} saved");
    Console.WriteLine($"From: {e.Message.From?.Address}");
    Console.WriteLine($"Subject: {e.Message.Subject}");
};

// Use custom store: .MessageStore(new JsonMessageStore(@"C:\email_storage"))
await server.StartAsync();

// Custom JSON-based message store
public class JsonMessageStore : IMessageStore
{
    private readonly string _directory;
    
    public JsonMessageStore(string directory)
    {
        _directory = directory;
        Directory.CreateDirectory(directory);
    }
    
    public async Task<bool> SaveAsync(
        ISmtpSession session, 
        ISmtpMessage message, 
        CancellationToken ct)
    {
        var dateFolder = Path.Combine(_directory, DateTime.Now.ToString("yyyy-MM-dd"));
        Directory.CreateDirectory(dateFolder);
        
        // Save raw message
        var emlFile = Path.Combine(dateFolder, $"{message.Id}.eml");
        await message.SaveToFileAsync(emlFile);
        
        // Save metadata as JSON
        var metadata = new {
          Id = message.Id,
          From = message.From?.Address,
          Recipients = message.Recipients.Select(r => r.Address).ToArray(),
          Subject = message.Subject,
          TextBody = message.TextBody,
          HtmlBody = message.HtmlBody,
          Size = message.Size,
          ReceivedDate = DateTime.UtcNow,
          SessionId = session.Id,
          RemoteEndPoint = (session.RemoteEndPoint as IPEndPoint)?.Address?.ToString(),
          IsAuthenticated = session.IsAuthenticated,
          AuthenticatedUser = session.AuthenticatedIdentity
        };
        
        var jsonFile = Path.Combine(dateFolder, $"{message.Id}.json");
        await File.WriteAllTextAsync(jsonFile, 
            JsonSerializer.Serialize(metadata, 
                new JsonSerializerOptions { WriteIndented = true }), ct);
        
        return true;
    }
}
Async/AwaitEvent-DrivenProduction Ready

Relay

Server with relay and smart host support

Advanced
RelayExample.cs
using Zetian.Server;
using Zetian.Relay.Extensions;
using Zetian.Relay.Configuration;
using System.Net;

// SMTP server with relay support
var server = SmtpServerBuilder
    .CreateBasic()
    .EnableRelay(config =>
    {
        // Primary smart host
        config.DefaultSmartHost = new SmartHostConfiguration
        {
            Host = "smtp.office365.com",
            Port = 587,
            Priority = 10,
            Credentials = new NetworkCredential("[email protected]", "password"),
            UseTls = true
        };
        
        // Backup smart host for failover
        config.SmartHosts.Add(new SmartHostConfiguration
        {
            Host = "backup.smtp.com",
            Port = 587,
            Priority = 20,
            Credentials = new NetworkCredential("user", "pass")
        });
        
        // Domain-specific routing
        config.DomainRouting["gmail.com"] = new SmartHostConfiguration
        {
            Host = "smtp.gmail.com",
            Port = 587,
            Credentials = new NetworkCredential("[email protected]", "app_password")
        };
        
        // MX routing for other domains
        config.UseMxRouting = true;
        config.DnsServers.Add(IPAddress.Parse("8.8.8.8"));
        
        // Retry configuration
        config.MaxRetryCount = 5;
        config.MessageLifetime = TimeSpan.FromDays(3);
        config.QueueProcessingInterval = TimeSpan.FromMinutes(1);
        
        // Enable bounce messages
        config.EnableBounceMessages = true;
        config.BounceSender = "[email protected]";
    });

// Monitor relay queue
server.MessageReceived += async (sender, e) =>
{
    // Queue message for relay with priority
    var priority = e.Message.From?.Address?.Contains("@vip.com") == true
        ? RelayPriority.Urgent
        : RelayPriority.Normal;
        
    await server.QueueForRelayAsync(e.Message, e.Session, priority);
    
    // Get relay statistics
    var stats = await server.GetRelayStatisticsAsync();
    Console.WriteLine($"Queued: {stats.QueuedMessages}, In Progress: {stats.InProgressMessages}");
};

// Start with relay service
var relayService = await server.StartWithRelayAsync();
Console.WriteLine("SMTP Server running with relay support");
Async/AwaitEvent-DrivenProduction Ready

AntiSpam

Server with comprehensive spam protection

Advanced
AntiSpamExample.cs
using Zetian.Server;
using Zetian.AntiSpam.Extensions;
using Zetian.AntiSpam.Checkers;

// SMTP server with anti-spam protection
var server = new SmtpServerBuilder()
    .Port(25)
    .ServerName("Protected SMTP Server")
    .Build();

// Configure comprehensive anti-spam
server.AddAntiSpam(builder => builder
    // SPF checking - verify sender authorization
    .EnableSpf(failScore: 50)
    
    // DKIM signature verification
    .EnableDkim(failScore: 40, strictMode: true)
    
    // DMARC policy enforcement
    .EnableDmarc(failScore: 70, quarantineScore: 50, enforcePolicy: true)
    
    // RBL/DNSBL checking
    .EnableRbl(
        "zen.spamhaus.org",
        "bl.spamcop.net",
        "b.barracudacentral.org"
    )
    
    // Bayesian filtering with training
    .EnableBayesian(spamThreshold: 0.85)
    
    // Greylisting for unknown senders
    .EnableGreylisting(initialDelay: TimeSpan.FromMinutes(5))
    
    // Configure thresholds
    .WithOptions(options =>
    {
        options.RejectThreshold = 60;        // Score >= 60 = reject
        options.TempFailThreshold = 40;      // Score >= 40 = temporary reject
        options.RunChecksInParallel = true;  // Parallel checking for performance
        options.CheckerTimeout = TimeSpan.FromSeconds(10);
        options.EnableDetailedLogging = true;
    }));

// Train Bayesian filter
var bayesianFilter = new BayesianSpamFilter();

// Load training data (example)
string[] spamSamples = {
    "Get rich quick! Click here now!!!",
    "Congratulations! You've won $1,000,000",
    "Cheap viagra online pharmacy"
};

string[] hamSamples = {
    "Meeting scheduled for tomorrow at 2pm",
    "Please find the attached invoice",
    "Thank you for your recent purchase"
};

// Train the filter
foreach (var spam in spamSamples)
    await bayesianFilter.TrainSpamAsync(spam);

foreach (var ham in hamSamples)
    await bayesianFilter.TrainHamAsync(ham);

// Add trained filter
server.AddSpamChecker(bayesianFilter);

// Monitor spam detection
server.MessageReceived += (sender, e) =>
{
    Console.WriteLine($"Message from {e.Message.From?.Address}");
    
    // Messages are automatically checked before this event
    // High-scoring spam will be rejected at SMTP level
};

// Custom spam checker for additional rules
public class CustomSpamChecker : ISpamChecker
{
    public string Name => "CustomRules";
    public bool IsEnabled { get; set; } = true;

    public async Task<SpamCheckResult> CheckAsync(
        ISmtpMessage message,
        ISmtpSession session,
        CancellationToken cancellationToken)
    {
        var subject = message.Subject?.ToLower() ?? "";
        
        // Check for suspicious patterns
        if (subject.Contains("lottery") || subject.Contains("winner"))
            return SpamCheckResult.Spam(80, "Lottery scam detected");
            
        // Check for excessive caps
        if (subject.Count(char.IsUpper) > subject.Length * 0.7)
            return SpamCheckResult.Spam(50, "Excessive capitalization");
            
        return SpamCheckResult.Clean(0);
    }
}

// Add custom checker
server.AddSpamChecker(new CustomSpamChecker());

await server.StartAsync();
Console.WriteLine("SMTP Server running with comprehensive anti-spam protection");
Async/AwaitEvent-DrivenProduction Ready

Health Monitoring

Server with health monitoring and custom checks

Advanced
HealthMonitoringExample.cs
using Zetian.Server;
using StackExchange.Redis;
using Microsoft.Data.SqlClient;
using Zetian.HealthCheck.Models;
using Zetian.HealthCheck.Extensions;

// SMTP server with health monitoring
using var server = new SmtpServerBuilder()
    .Port(25)
    .MaxConnections(100)
    .MaxMessageSizeMB(10)
    .Build();

// Monitor server metrics
server.MessageReceived += (sender, e) => {
    var sessionCount = server.Configuration.MaxConnections; // Active sessions
    Console.WriteLine($"Active sessions: {sessionCount}");

    if (sessionCount > 80)
    {
        Console.WriteLine("WARNING: High connection count!");
    }
};

// Start server and health check with custom checks configuration
await server.StartWithHealthCheckAsync(8080, healthService =>
{
    // Add custom health checks
    healthService.AddHealthCheck("database", async (ct) =>
    {
        try
        {
            // Check database connection
            using var connection = new SqlConnection("Server=...;Database=...;User ID=...;Password=...;");
            await connection.OpenAsync(ct);
            return HealthCheckResult.Healthy("Database connected");
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy("Cannot connect to database", ex);
        }
    });

    // Add Redis check
    healthService.AddHealthCheck("redis", async (ct) =>
    {
        try
        {
            // Check Redis connection
            var redis = ConnectionMultiplexer.Connect("localhost:6379");
            var db = redis.GetDatabase();
            await db.PingAsync();
            return HealthCheckResult.Healthy("Redis is responsive");
        }
        catch (Exception ex)
        {
            // Redis down is not critical, mark as degraded
            return HealthCheckResult.Degraded("Redis not available", ex);
        }
    });
});

Console.WriteLine("Server running with health monitoring");
Console.WriteLine("Health endpoints:");
Console.WriteLine("  http://localhost:8080/health - Overall status");
Console.WriteLine("  http://localhost:8080/health/livez  - Liveness check");
Console.WriteLine("  http://localhost:8080/health/readyz - Readiness check");
Async/AwaitEvent-DrivenProduction Ready

Monitoring

Server with Prometheus and OpenTelemetry metrics

Advanced
MonitoringExample.cs
using Zetian.Server;
using Zetian.Monitoring.Extensions;

// Create SMTP server
var server = SmtpServerBuilder
    .CreateBasic();

// Enable comprehensive monitoring
server.EnableMonitoring(builder => builder
    // Prometheus exporter on port 9090
    .EnablePrometheus(9090)
    
    // OpenTelemetry integration
    .EnableOpenTelemetry("http://localhost:4317")
    
    // Service identification
    .WithServiceName("smtp-production")
    .WithServiceVersion("1.0.0")
    
    // Detailed metrics
    .EnableDetailedMetrics()
    .EnableCommandMetrics()
    .EnableThroughputMetrics()
    .EnableHistograms()
    
    // Update interval
    .WithUpdateInterval(TimeSpan.FromSeconds(10))
    
    // Custom labels for all metrics
    .WithLabels(
        ("environment", "production"),
        ("region", "us-east-1"),
        ("instance", "smtp-01"))
    
    // Histogram buckets for command duration (milliseconds)
    .WithCommandDurationBuckets(1, 5, 10, 25, 50, 100, 250, 500, 1000)
    
    // Histogram buckets for message size (bytes)
    .WithMessageSizeBuckets(1024, 10240, 102400, 1048576, 10485760));

// Monitor server events
server.SessionCompleted += (sender, e) =>
{
    var stats = server.GetStatistics();
    Console.WriteLine($"Active Sessions: {stats?.ActiveSessions}");
    Console.WriteLine($"Messages/sec: {stats?.CurrentThroughput?.MessagesPerSecond}");
    Console.WriteLine($"Delivery Rate: {stats?.DeliveryRate}%");
};

// Custom metrics recording
server.MessageReceived += (sender, e) =>
{
    // Record custom metrics
    server.RecordMetric("CUSTOM_PROCESSING", success: true, durationMs: 42.5);
    
    // Access metrics collector
    var collector = server.GetMetricsCollector();
    if (e.Message.Size > 10_000_000)
    {
        collector.RecordRejection("Message too large");
    }
};

// Start server
await server.StartAsync();
Console.WriteLine("SMTP Server with monitoring on port 25");
Console.WriteLine("Prometheus metrics available at http://localhost:9090/metrics");

// Get real-time statistics
while (!Console.KeyAvailable)
{
    var stats = server.GetStatistics();
    Console.Clear();
    Console.WriteLine("=== Server Statistics ===");
    Console.WriteLine($"Uptime: {stats.Uptime}");
    Console.WriteLine($"Total Sessions: {stats.TotalSessions}");
    Console.WriteLine($"Active Sessions: {stats.ActiveSessions}");
    Console.WriteLine($"Messages/sec: {stats.CurrentThroughput?.MessagesPerSecond}");
    Console.WriteLine($"Bytes/sec: {stats.CurrentThroughput?.BytesPerSecond}");
    Console.WriteLine($"TLS Usage: {stats.ConnectionMetrics?.TlsUsageRate}%");
    await Task.Delay(5000);
}
Async/AwaitEvent-DrivenProduction Ready

Looking for More Examples?

Find more examples and test scenarios in our GitHub repository.

View All Examples on GitHub