# SmartPool Usage Examples Các ví dụ sử dụng SmartPool trong thực tế. ## 1. Basic Setup - Client Service ### Cấu hình trong appsettings.json ```json { "SmartPool": { "Protocol": "Grpc", "Host": "smartpool-api.internal.com", "Port": 5001, "UseSecureConnection": false, "DefaultAccessToken": "service-crawler-001", "TimeoutMs": 30000 } } ``` ### Đăng ký trong Program.cs ```csharp using Icomm.SmartPool.Proxy.Extensions; var builder = WebApplication.CreateBuilder(args); // Đăng ký SmartPool client builder.Services.AddSmartPoolClient(builder.Configuration); // Hoặc cấu hình trực tiếp builder.Services.AddSmartPoolClient(options => { options.Protocol = SmartPoolProtocol.Grpc; options.Host = "smartpool-api.internal.com"; options.Port = 5001; options.DefaultAccessToken = "service-crawler-001"; }); var app = builder.Build(); app.Run(); ``` ## 2. Random Strategy - Crawl đơn giản ```csharp public class FacebookCrawlerService { private readonly ISmartPoolClient _smartPoolClient; private readonly ILogger _logger; public FacebookCrawlerService( ISmartPoolClient smartPoolClient, ILogger logger) { _smartPoolClient = smartPoolClient; _logger = logger; } public async Task CrawlPageAsync(string url) { // Lấy proxy ngẫu nhiên var proxy = await _smartPoolClient.GetProxyAsync( strategy: "random", ipVersion: "v6", country: "US" ); if (proxy == null) { _logger.LogWarning("No proxy available"); return null; } var handler = new HttpClientHandler { Proxy = proxy }; var httpClient = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) }; var stopwatch = Stopwatch.StartNew(); try { var response = await httpClient.GetAsync(url); stopwatch.Stop(); // Log usage await _smartPoolClient.LogProxyUsageAsync( accessToken: "service-crawler-001", proxyId: GetProxyIdFromProxy(proxy), // Helper method targetDomain: "facebook.com", statusCode: (int)response.StatusCode, responseTimeMs: (int)stopwatch.ElapsedMilliseconds ); return await response.Content.ReadAsStringAsync(); } catch (Exception ex) { stopwatch.Stop(); _logger.LogError(ex, "Failed to crawl {Url}", url); // Log failed usage await _smartPoolClient.LogProxyUsageAsync( accessToken: "service-crawler-001", proxyId: GetProxyIdFromProxy(proxy), targetDomain: "facebook.com", statusCode: 0, responseTimeMs: (int)stopwatch.ElapsedMilliseconds, errorMessage: ex.Message ); return null; } } } ``` ## 3. Least Delay Strategy - Tối ưu tốc độ ```csharp public class HighSpeedCrawlerService { private readonly ISmartPoolClient _smartPoolClient; public async Task> CrawlMultipleUrlsAsync(List urls) { var results = new List(); foreach (var url in urls) { // Lấy proxy nhanh nhất cho domain cụ thể var proxy = await _smartPoolClient.GetProxyAsync( strategy: "least_delay", targetDomain: ExtractDomain(url), // facebook.com, x.com, etc. ipVersion: "v6" ); if (proxy != null) { var content = await CrawlWithProxyAsync(url, proxy); results.Add(content); } } return results; } private string ExtractDomain(string url) { var uri = new Uri(url); return uri.Host; } } ``` ## 4. Adaptive Ranking Strategy - Độ tin cậy cao ```csharp public class ReliableCrawlerService { private readonly ISmartPoolClient _smartPoolClient; public async Task CrawlWithBestProxyAsync(string url) { // Lấy proxy có success rate cao nhất var proxy = await _smartPoolClient.GetProxyAsync( strategy: "adaptive_ranking", targetDomain: "facebook.com", ipVersion: "v6", country: "US" ); if (proxy == null) { throw new Exception("No reliable proxy available"); } return await CrawlWithProxyAsync(url, proxy); } } ``` ## 5. Alternative Strategy - Retry với proxy khác ```csharp public class ResilientCrawlerService { private readonly ISmartPoolClient _smartPoolClient; private const int MaxRetries = 3; public async Task CrawlWithRetryAsync(string url) { SmartProxyServer currentProxy = null; Exception lastException = null; for (int attempt = 0; attempt < MaxRetries; attempt++) { try { if (attempt == 0) { // Lần đầu: dùng random hoặc least_delay var proxy = await _smartPoolClient.GetProxyAsync( strategy: "least_delay", targetDomain: "facebook.com" ); currentProxy = await GetRawProxyInfo(proxy); } else { // Retry: tìm proxy thay thế tương tự var request = new GetProxyRequest { AccessToken = "service-crawler-001", Strategy = "alternative", RefererProxy = currentProxy, // Proxy vừa fail TargetDomain = "facebook.com" }; currentProxy = await _smartPoolClient.GetRawProxyAsync(request); } if (currentProxy == null) { throw new Exception("No alternative proxy available"); } // Thử crawl var result = await CrawlWithProxyAsync(url, currentProxy.ToWebProxy()); return result; } catch (Exception ex) { lastException = ex; await Task.Delay(1000 * (attempt + 1)); // Exponential backoff } } throw new Exception($"Failed after {MaxRetries} attempts", lastException); } private async Task GetRawProxyInfo(IWebProxy proxy) { // Helper để lấy thông tin raw proxy từ IWebProxy // Implementation depends on your needs return null; } } ``` ## 6. Round Robin Strategy - Phân tải đều ```csharp public class LoadBalancedCrawlerService { private readonly ISmartPoolClient _smartPoolClient; public async Task CrawlManyPagesAsync(List urls) { // Round robin sẽ tự động phân phối đều các request var tasks = urls.Select(async url => { var proxy = await _smartPoolClient.GetProxyAsync( strategy: "round_robin", country: "US" ); return await CrawlWithProxyAsync(url, proxy); }); await Task.WhenAll(tasks); } } ``` ## 7. Mixed Strategy - Kết hợp nhiều chiến lược ```csharp public class SmartCrawlerService { private readonly ISmartPoolClient _smartPoolClient; private readonly Dictionary _domainStrategies = new() { ["facebook.com"] = "adaptive_ranking", // Cần độ tin cậy cao ["x.com"] = "least_delay", // Cần tốc độ ["instagram.com"] = "round_robin" // Phân tải đều }; public async Task CrawlSmartAsync(string url) { var domain = ExtractDomain(url); var strategy = _domainStrategies.GetValueOrDefault(domain, "random"); var proxy = await _smartPoolClient.GetProxyAsync( strategy: strategy, targetDomain: domain, ipVersion: "v6" ); return await CrawlWithProxyAsync(url, proxy); } } ``` ## 8. Logging Best Practices ```csharp public class ProxyLoggingService { private readonly ISmartPoolClient _smartPoolClient; public async Task LogDetailedUsageAsync( int proxyId, string targetDomain, HttpResponseMessage response, TimeSpan duration, Exception exception = null) { var request = new ProxyUsageLogRequest { AccessToken = "service-crawler-001", ProxyId = proxyId, TargetDomain = targetDomain, StatusCode = exception != null ? 0 : (int)response.StatusCode, ResponseTimeMs = (int)duration.TotalMilliseconds, ErrorMessage = exception?.Message, RequestId = Guid.NewGuid().ToString("N") }; await _smartPoolClient.LogProxyUsageAsync(request); } } ``` ## 9. Health Check Integration ```csharp public class SmartPoolHealthCheck : IHealthCheck { private readonly ISmartPoolClient _smartPoolClient; public SmartPoolHealthCheck(ISmartPoolClient smartPoolClient) { _smartPoolClient = smartPoolClient; } public async Task CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { try { var isHealthy = await _smartPoolClient.PingAsync(cancellationToken); if (isHealthy) { return HealthCheckResult.Healthy("SmartPool API is responding"); } else { return HealthCheckResult.Unhealthy("SmartPool API is not responding"); } } catch (Exception ex) { return HealthCheckResult.Unhealthy( "SmartPool API connection failed", ex); } } } // Đăng ký trong Program.cs builder.Services.AddHealthChecks() .AddCheck("smartpool"); ``` ## 10. Dependency Injection Pattern ```csharp // Interface cho service của bạn public interface ICrawlerService { Task CrawlAsync(string url); } // Implementation public class CrawlerService : ICrawlerService { private readonly ISmartPoolClient _smartPoolClient; private readonly ILogger _logger; private readonly IHttpClientFactory _httpClientFactory; public CrawlerService( ISmartPoolClient smartPoolClient, ILogger logger, IHttpClientFactory httpClientFactory) { _smartPoolClient = smartPoolClient; _logger = logger; _httpClientFactory = httpClientFactory; } public async Task CrawlAsync(string url) { var proxy = await _smartPoolClient.GetProxyAsync( strategy: "adaptive_ranking", targetDomain: ExtractDomain(url) ); if (proxy == null) { _logger.LogWarning("No proxy available for {Url}", url); return null; } var handler = new HttpClientHandler { Proxy = proxy }; var httpClient = _httpClientFactory.CreateClient(); httpClient = new HttpClient(handler); try { var response = await httpClient.GetAsync(url); return await response.Content.ReadAsStringAsync(); } catch (Exception ex) { _logger.LogError(ex, "Crawl failed for {Url}", url); return null; } } private string ExtractDomain(string url) => new Uri(url).Host; } // Đăng ký trong Program.cs builder.Services.AddSmartPoolClient(builder.Configuration); builder.Services.AddScoped(); ``` ## 11. Configuration per Environment ```csharp // appsettings.Development.json { "SmartPool": { "Protocol": "Http", // Dễ debug hơn "Host": "localhost", "Port": 5000 } } // appsettings.Production.json { "SmartPool": { "Protocol": "Grpc", // Performance cao hơn "Host": "smartpool-api.internal.com", "Port": 5001, "UseSecureConnection": true } } ``` ## 12. Error Handling Pattern ```csharp public class SafeCrawlerService { private readonly ISmartPoolClient _smartPoolClient; private readonly ILogger _logger; public async Task CrawlSafelyAsync(string url) { try { var proxy = await _smartPoolClient.GetProxyAsync( strategy: "adaptive_ranking", targetDomain: ExtractDomain(url) ); if (proxy == null) { return CrawlResult.Failed("No proxy available"); } var content = await CrawlWithProxyAsync(url, proxy); return CrawlResult.Success(content); } catch (TaskCanceledException) { _logger.LogWarning("Crawl timeout for {Url}", url); return CrawlResult.Failed("Timeout"); } catch (HttpRequestException ex) { _logger.LogError(ex, "HTTP error for {Url}", url); return CrawlResult.Failed($"HTTP Error: {ex.Message}"); } catch (Exception ex) { _logger.LogError(ex, "Unexpected error for {Url}", url); return CrawlResult.Failed($"Error: {ex.Message}"); } } } public class CrawlResult { public bool IsSuccess { get; set; } public string Content { get; set; } public string ErrorMessage { get; set; } public static CrawlResult Success(string content) => new() { IsSuccess = true, Content = content }; public static CrawlResult Failed(string error) => new() { IsSuccess = false, ErrorMessage = error }; } ``` ## Kết luận Các ví dụ trên minh họa cách sử dụng SmartPool trong nhiều tình huống thực tế: - ✅ Basic setup và configuration - ✅ 5 strategies với use cases cụ thể - ✅ Retry logic với alternative strategy - ✅ Health check integration - ✅ Error handling patterns - ✅ Logging best practices - ✅ Dependency injection - ✅ Multi-environment configuration