19 KiB
Icomm.SmartPool.Proxy
Client SDK for SmartPool proxy management system. Supports both gRPC and HTTP protocols.
📖 Xem tài liệu chi tiết: SDK_DOCUMENTATION.md
📌 Migration note (quan trọng): CLIENT_MIGRATION_NOTES.md
✨ Features
- ✅ Dual Protocol: gRPC (MagicOnion) và HTTP REST API
- ✅ 5 Chiến lược: Random, Round Robin, Least Delay, Adaptive Ranking, Alternative
- ✅ Tối ưu hiệu suất: Keep-alive, Connection pooling, Client caching, Compression
- ✅ Batch Logging: Ghi log hiệu quả với batch processing
- ✅ Fire-and-Forget: Non-blocking logging
- ✅ Compact Response: Giảm payload size ~50-60%
Installation
Prerequisites
Đảm bảo bạn đã cấu hình NuGet source ic trong project:
# Thêm NuGet source (nếu chưa có)
dotnet nuget add source <nuget-feed-url> --name ic
Install via NuGet Package
Cài đặt package từ NuGet repository:
dotnet add package --source ic --version 10.0.1 Icomm.SmartPool.Proxy
Hoặc thêm vào .csproj file:
<ItemGroup>
<PackageReference Include="Icomm.SmartPool.Proxy" Version="10.0.1" />
</ItemGroup>
Và cấu hình NuGet source trong nuget.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="ic" value="<nuget-feed-url>" />
</packageSources>
</configuration>
Quick Start
Configuration
Add to appsettings.json:
{
"SmartPool": {
"Protocol": "Grpc",
"Host": "localhost",
"Port": 5001,
"UseSecureConnection": false,
"DefaultAccessToken": "your-access-token",
"RequestTimeoutMs": 30000,
"LogRequestTimeoutMs": 3000,
"LogRetryMaxBatchSize": 50,
"LogRetryFlushIntervalMs": 5000
}
}
Register in DI Container
using Icomm.SmartPool.Proxy.Extensions;
// In Startup.cs or Program.cs
services.AddSmartPoolClient(configuration);
Use in Your Code
public class MyService
{
private readonly ISmartPoolClient _smartPoolClient;
public MyService(ISmartPoolClient smartPoolClient)
{
_smartPoolClient = smartPoolClient;
}
public async Task MakeRequestAsync()
{
// Get proxy as IWebProxy (ready for HttpClient)
var request = new GetProxyRequest
{
access_token = "your-token",
strategy = "least_delay",
target_domain = "facebook.com",
ip_version = "v6"
};
var proxy = await _smartPoolClient.GetProxyAsync(request);
if (proxy != null)
{
var handler = new HttpClientHandler { Proxy = proxy };
var httpClient = new HttpClient(handler);
var response = await httpClient.GetAsync("https://facebook.com");
// Log usage
var logRequest = new ProxyUsageLogRequest
{
access_token = "your-token",
proxy_id = 123, // Get from GetRawProxyAsync if needed
target_domain = "facebook.com",
status_code = (int)response.StatusCode,
response_time_ms = 450
};
await _smartPoolClient.LogProxyUsageAsync(logRequest);
}
}
}
Advanced Usage
Get Raw Proxy Information
var request = new GetProxyRequest
{
access_token = "your-token",
strategy = "adaptive_ranking",
target_domain = "facebook.com",
ip_version = "v6",
protocol = "http",
country = "US"
};
var proxyServer = await _smartPoolClient.GetRawProxyAsync(request);
if (proxyServer != null)
{
Console.WriteLine($"Proxy: {proxyServer.host}:{proxyServer.port}");
Console.WriteLine($"Country: {proxyServer.country}");
}
Alternative Proxy Strategy
var request = new GetProxyRequest
{
access_token = "your-token",
strategy = "alternative",
referer_proxy = new SmartProxyServer { id = 123 } // Current proxy that failed
};
var alternativeProxy = await _smartPoolClient.GetRawProxyAsync(request);
Strategies
- random: Random selection
- round_robin: Balanced distribution (default)
- least_delay: Fastest proxy (requires
target_domain) - adaptive_ranking: Highest success rate (requires
target_domain) - alternative: Similar proxy replacement (requires
referer_proxy.id)
Protocol Selection
gRPC (Recommended)
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Grpc;
options.Host = "api.example.com";
options.Port = 5001;
});
Pros: High performance, binary protocol, streaming support
HTTP
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Http;
options.Host = "api.example.com";
options.Port = 5000;
});
Pros: Standard REST API, easier debugging, firewall-friendly
Error Handling
SDK cung cấp exception handling chi tiết với các exception types tương ứng với error codes từ server:
Exception Types
using Icomm.SmartPool.Proxy.Exceptions;
try
{
var proxy = await _smartPoolClient.GetRawProxyAsync(request);
// Use proxy...
}
catch (AccessTokenRequiredException)
{
// Access token không được cung cấp
Console.WriteLine("Access token is required");
}
catch (AccessTokenInvalidException ex)
{
// Access token không hợp lệ hoặc không được phân quyền
Console.WriteLine($"Invalid access token: {ex.AccessToken}");
}
catch (NoAvailableProxiesException ex)
{
// Không có proxy available cho access token này
Console.WriteLine($"No proxies available for token: {ex.AccessToken}");
}
catch (NoMatchingProxiesException)
{
// Không có proxy match với filters (ip_version, protocol, country, etc.)
Console.WriteLine("No proxies match the specified filters");
}
catch (StrategyNotFoundException ex)
{
// Strategy không tồn tại
Console.WriteLine($"Strategy not found: {ex.StrategyName}");
}
catch (RefererProxyRequiredException)
{
// Alternative strategy cần referer_proxy
Console.WriteLine("Referer proxy is required for alternative strategy");
}
catch (SmartPoolException ex)
{
// Các lỗi khác từ SmartPool
Console.WriteLine($"SmartPool error ({ex.ErrorCode}): {ex.Message}");
}
catch (Exception ex)
{
// Network errors, timeout, etc.
Console.WriteLine($"Network error: {ex.Message}");
}
Try Methods (Không Throw Exception)
SDK cung cấp các method Try* để bỏ qua exceptions và trả về null nếu lỗi:
// TryGetRawProxyAsync - không throw exception
var proxy = await _smartPoolClient.TryGetRawProxyAsync(request);
if (proxy != null)
{
// Sử dụng proxy
Console.WriteLine($"Proxy: {proxy.host}:{proxy.port}");
}
else
{
// Xử lý khi không lấy được proxy (silent failure)
Console.WriteLine("Failed to get proxy");
}
// TryGetProxyAsync - không throw exception
var webProxy = await _smartPoolClient.TryGetProxyAsync(request);
if (webProxy != null)
{
var handler = new HttpClientHandler { Proxy = webProxy };
var httpClient = new HttpClient(handler);
// Use httpClient...
}
Khi nào dùng Try methods:
- Khi bạn muốn xử lý lỗi một cách silent (không cần biết chi tiết lỗi)
- Trong retry logic, khi bạn chỉ cần biết success/failure
- Khi performance quan trọng hơn error details
Health Check
var isHealthy = await _smartPoolClient.PingAsync();
if (!isHealthy)
{
Console.WriteLine("SmartPool API is not responding");
}
Performance Optimizations
SDK đã được tối ưu với các tính năng:
- Connection Pooling & Keep-Alive: Giảm latency reconnect từ ~50-100ms xuống ~5ms
- Client-side Caching: Giảm network calls ~90% khi cache hit
- Response Compression: Giảm payload size ~30-50%
- Batch Logging: Giảm N network calls → 1 call
- Fire-and-Forget: Non-blocking logging, không block main flow
Xem chi tiết trong SDK_DOCUMENTATION.md.
Chi Tiết Các Modes và Cách Hoạt Động
1. Protocol Modes
gRPC Mode (Khuyến nghị)
Cách hoạt động:
- Sử dụng HTTP/2 với binary protocol (MessagePack)
- Connection pooling tự động với keep-alive
- Compression tự động (gzip/deflate)
- Streaming support cho batch operations
Cấu hình:
{
"SmartPool": {
"Protocol": "Grpc",
"Host": "api.example.com",
"Port": 5001,
"UseSecureConnection": true,
"EnableCompression": true,
"CompressionAlgorithm": "gzip"
}
}
Khi nào dùng:
- ✅ High-performance scenarios (scraping, batch processing)
- ✅ Internal services (microservices communication)
- ✅ Khi cần throughput cao
- ✅ Khi có control over network (không bị firewall block HTTP/2)
Ưu điểm:
- Performance cao hơn HTTP ~30-50%
- Binary protocol → payload nhỏ hơn
- Connection pooling tự động
- Keep-alive giảm latency
Nhược điểm:
- Cần HTTP/2 support
- Khó debug hơn (binary format)
- Có thể bị firewall block
HTTP Mode
Cách hoạt động:
- Standard HTTP/1.1 REST API
- JSON serialization
- Standard HttpClient với connection pooling
- Dễ debug với browser DevTools
Cấu hình:
{
"SmartPool": {
"Protocol": "Http",
"Host": "api.example.com",
"Port": 5000,
"UseSecureConnection": true
}
}
Khi nào dùng:
- ✅ External clients (web browsers, mobile apps)
- ✅ Khi cần debug dễ dàng
- ✅ Khi firewall chỉ cho phép HTTP
- ✅ Development/testing environments
Ưu điểm:
- Dễ debug (JSON, có thể test với Postman/curl)
- Universal support (mọi client đều hỗ trợ HTTP)
- Firewall-friendly
- Standard REST API
Nhược điểm:
- Performance thấp hơn gRPC
- Payload lớn hơn (JSON vs binary)
- Không có streaming support
2. Client-Side Caching Mode
Cách hoạt động:
- Cache proxy results trong memory (MemoryCache)
- Cache key dựa trên: access_token, strategy, filters (ip_version, protocol, country, target_domain)
- TTL:
ClientCacheDurationSeconds(default: 30s) - Sliding expiration: 50% của TTL
- Max entries:
ClientCacheMaxEntries(default: 100)
Flow:
1. Request proxy với filters
2. Check cache → Cache hit? Return cached proxy
3. Cache miss? Call API → Cache result → Return proxy
4. Next request với same filters → Return từ cache (không call API)
Cấu hình:
{
"SmartPool": {
"EnableClientCache": true,
"ClientCacheDurationSeconds": 30,
"ClientCacheMaxEntries": 100
}
}
Khi nào dùng:
- ✅ Khi request cùng filters nhiều lần
- ✅ Random/Round-robin strategies (không phụ thuộc vào real-time data)
- ✅ Giảm load cho API server
- ✅ Giảm latency cho client
Khi KHÔNG nên dùng:
- ❌ Least Delay strategy (cần real-time data)
- ❌ Adaptive Ranking strategy (cần real-time data)
- ❌ Khi cần proxy mới mỗi lần request
Ví dụ:
// Request 1: Call API, cache result
var proxy1 = await _client.GetProxyAsync(new GetProxyRequest
{
strategy = "random",
ip_version = "v6"
});
// Request 2: Return từ cache (không call API)
var proxy2 = await _client.GetProxyAsync(new GetProxyRequest
{
strategy = "random",
ip_version = "v6"
});
// proxy1 và proxy2 giống nhau (cùng từ cache)
// Request 3: Khác filters → Call API mới
var proxy3 = await _client.GetProxyAsync(new GetProxyRequest
{
strategy = "random",
ip_version = "v4" // Khác filter
});
3. Logging Modes
Fire-and-Forget Mode
Cách hoạt động:
- Logging chạy trong background task (không block main thread)
- Nếu có batch logging → Queue vào channel
- Nếu không có batch → Fire task riêng
- Không đợi response từ server
Cấu hình:
{
"SmartPool": {
"EnableFireAndForgetLogging": true
}
}
Khi nào dùng:
- ✅ High-throughput scenarios
- ✅ Khi logging không critical (best-effort)
- ✅ Khi không muốn block main flow
- ✅ Background processing
Ví dụ:
// Non-blocking - không đợi response
await _client.LogProxyUsageAsync(new ProxyUsageLogRequest
{
proxy_id = 123,
status_code = 200,
response_time_ms = 450
});
// Code tiếp tục chạy ngay, không đợi log complete
Batch Logging Mode
Cách hoạt động:
- Queue log requests vào bounded channel
- Background task collect logs theo batch
- Flush khi đạt
LogBatchSizehoặcLogBatchFlushIntervalMs - Gửi batch đến server
Flow:
1. LogProxyUsageAsync() → Queue vào channel
2. Background task collect logs
3. Khi đủ LogBatchSize (50) hoặc timeout (5s) → Flush batch
4. Gửi batch đến server
Cấu hình:
{
"SmartPool": {
"EnableBatchLogging": true,
"LogBatchSize": 50,
"LogBatchFlushIntervalMs": 5000
}
}
Khi nào dùng:
- ✅ High-throughput scenarios (1000+ requests/second)
- ✅ Khi muốn giảm network calls
- ✅ Khi có nhiều logs cần gửi
Ví dụ:
// Queue 1000 logs
for (int i = 0; i < 1000; i++)
{
_client.QueueLogProxyUsage(new ProxyUsageLogRequest
{
proxy_id = i,
status_code = 200,
response_time_ms = 450
});
}
// Chỉ gửi ~20 batches (50 logs/batch) thay vì 1000 requests
Kết hợp Fire-and-Forget + Batch:
{
"SmartPool": {
"EnableFireAndForgetLogging": true,
"EnableBatchLogging": true,
"LogBatchSize": 50,
"LogBatchFlushIntervalMs": 5000
}
}
→ Logging hoàn toàn non-blocking và batch processing
Synchronous Logging Mode
Cách hoạt động:
- Đợi response từ server
- Block cho đến khi log complete
- Throw exception nếu lỗi
Cấu hình:
{
"SmartPool": {
"EnableFireAndForgetLogging": false,
"EnableBatchLogging": false
}
}
Khi nào dùng:
- ✅ Khi logging là critical (cần đảm bảo log được gửi)
- ✅ Low-throughput scenarios
- ✅ Debug/testing
Ví dụ:
// Blocking - đợi response
var success = await _client.LogProxyUsageAsync(new ProxyUsageLogRequest
{
proxy_id = 123,
status_code = 200
});
if (!success)
{
// Handle failure
}
4. Connection Pooling & Keep-Alive Mode
Cách hoạt động:
gRPC:
- HTTP/2 connection pooling tự động
- Keep-alive ping mỗi
KeepAlivePingDelaySeconds(60s) - Ping timeout:
KeepAlivePingTimeoutSeconds(30s) - Connection idle timeout:
PooledConnectionIdleTimeoutMinutes(5min) - Connection lifetime:
PooledConnectionLifetimeMinutes(10min)
HTTP:
- HttpClient connection pooling
- Connection idle timeout:
PooledConnectionIdleTimeoutMinutes(5min) - Connection lifetime:
PooledConnectionLifetimeMinutes(10min)
Cấu hình:
{
"SmartPool": {
"KeepAlivePingDelaySeconds": 60,
"KeepAlivePingTimeoutSeconds": 30,
"PooledConnectionIdleTimeoutMinutes": 5,
"PooledConnectionLifetimeMinutes": 10,
"EnableMultipleHttp2Connections": true,
"ConnectTimeoutSeconds": 5
}
}
Lợi ích:
- Giảm latency: Reuse connection thay vì tạo mới (~50-100ms → ~5ms)
- Giảm overhead: Không cần handshake mỗi request
- Better throughput: Multiple connections cho parallel requests
Ví dụ:
// Request 1: Tạo connection mới (~50ms)
var proxy1 = await _client.GetProxyAsync();
// Request 2-100: Reuse connection (~5ms mỗi request)
for (int i = 0; i < 100; i++)
{
var proxy = await _client.GetProxyAsync();
}
// Total time: ~50ms + (99 * 5ms) = ~545ms
// Without pooling: ~100 * 50ms = ~5000ms
5. Compression Mode
Cách hoạt động:
- gRPC: Compression tự động với gzip/deflate
- HTTP: Accept-Encoding header
- Server compress response nếu client support
Cấu hình:
{
"SmartPool": {
"EnableCompression": true,
"CompressionAlgorithm": "gzip"
}
}
Lợi ích:
- Giảm payload size ~30-50%
- Giảm bandwidth usage
- Faster transfer trên slow networks
Khi nào dùng:
- ✅ Khi bandwidth là bottleneck
- ✅ Mobile networks
- ✅ High-latency networks
- ✅ Khi response size lớn
Trade-off:
- CPU overhead cho compression/decompression
- Thường không đáng kể với modern CPUs
Best Practices
1. Protocol Selection
// High-performance internal service → gRPC
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Grpc;
});
// External client → HTTP
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Http;
});
2. Caching Strategy
// Random/Round-robin → Enable cache
services.AddSmartPoolClient(options =>
{
options.EnableClientCache = true;
options.ClientCacheDurationSeconds = 30;
});
// Least Delay/Adaptive Ranking → Disable cache
services.AddSmartPoolClient(options =>
{
options.EnableClientCache = false; // Cần real-time data
});
3. Logging Strategy
// High-throughput → Fire-and-forget + Batch
services.AddSmartPoolClient(options =>
{
options.EnableFireAndForgetLogging = true;
options.EnableBatchLogging = true;
options.LogBatchSize = 50;
});
// Critical logging → Synchronous
services.AddSmartPoolClient(options =>
{
options.EnableFireAndForgetLogging = false;
options.EnableBatchLogging = false;
});
4. Error Handling Pattern
// Detailed error handling
try
{
var proxy = await _client.GetRawProxyAsync(request);
}
catch (NoAvailableProxiesException)
{
// Retry với different token hoặc wait
}
catch (NoMatchingProxiesException)
{
// Relax filters hoặc use different strategy
}
catch (SmartPoolException ex)
{
_logger.LogError(ex, "SmartPool error: {ErrorCode}", ex.ErrorCode);
}
// Silent failure
var proxy = await _client.TryGetRawProxyAsync(request);
if (proxy == null)
{
// Fallback logic
}
5. Retry Pattern với Alternative Strategy
SmartProxyServer? currentProxy = null;
for (int retry = 0; retry < 3; retry++)
{
try
{
var request = retry == 0
? new GetProxyRequest { strategy = "least_delay", target_domain = "facebook.com" }
: new GetProxyRequest
{
strategy = "alternative",
referer_proxy = currentProxy
};
currentProxy = await _client.GetRawProxyAsync(request);
// Use proxy...
break; // Success
}
catch (NoMatchingProxiesException)
{
if (retry == 2) throw; // Last retry failed
// Continue to next retry
}
}
Dependencies
- .NET 10.0
- MagicOnion.Client 6.1.7
- Microsoft.Extensions.* 10.0.2
Documentation
- 📖 SDK Documentation - Tài liệu chi tiết đầy đủ
- 📖 System README - Tổng quan hệ thống
License
Internal use only.