diff --git a/CryptoExchange.Net/LibraryHelpers.cs b/CryptoExchange.Net/LibraryHelpers.cs
index 1113620..a223b39 100644
--- a/CryptoExchange.Net/LibraryHelpers.cs
+++ b/CryptoExchange.Net/LibraryHelpers.cs
@@ -1,4 +1,5 @@
using CryptoExchange.Net.Objects;
+using CryptoExchange.Net.Objects.Options;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@@ -105,31 +106,36 @@ namespace CryptoExchange.Net
///
/// Create a new HttpMessageHandler instance
///
- public static HttpMessageHandler CreateHttpClientMessageHandler(ApiProxy? proxy, TimeSpan? keepAliveInterval)
+ public static HttpMessageHandler CreateHttpClientMessageHandler(RestExchangeOptions options)
{
#if NET5_0_OR_GREATER
var socketHandler = new SocketsHttpHandler();
try
{
- if (keepAliveInterval != null && keepAliveInterval != TimeSpan.Zero)
+ if (options.HttpKeepAliveInterval != null && options.HttpKeepAliveInterval != TimeSpan.Zero)
{
socketHandler.KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always;
- socketHandler.KeepAlivePingDelay = keepAliveInterval.Value;
+ socketHandler.KeepAlivePingDelay = options.HttpKeepAliveInterval.Value;
socketHandler.KeepAlivePingTimeout = TimeSpan.FromSeconds(10);
}
socketHandler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
socketHandler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
+
+ socketHandler.EnableMultipleHttp2Connections = options.HttpEnableMultipleHttp2Connections;
+ socketHandler.PooledConnectionLifetime = options.HttpPooledConnectionLifetime;
+ socketHandler.PooledConnectionIdleTimeout = options.HttpPooledConnectionIdleTimeout;
+ socketHandler.MaxConnectionsPerServer = options.HttpMaxConnectionsPerServer;
}
catch (PlatformNotSupportedException) { }
catch (NotImplementedException) { } // Mono runtime throws NotImplementedException
- if (proxy != null)
+ if (options.Proxy != null)
{
socketHandler.Proxy = new WebProxy
{
- Address = new Uri($"{proxy.Host}:{proxy.Port}"),
- Credentials = proxy.Password == null ? null : new NetworkCredential(proxy.Login, proxy.Password)
+ Address = new Uri($"{options.Proxy.Host}:{options.Proxy.Port}"),
+ Credentials = options.Proxy.Password == null ? null : new NetworkCredential(options.Proxy.Login, options.Proxy.Password)
};
}
return socketHandler;
@@ -143,12 +149,12 @@ namespace CryptoExchange.Net
catch (PlatformNotSupportedException) { }
catch (NotImplementedException) { } // Mono runtime throws NotImplementedException
- if (proxy != null)
+ if (options.Proxy != null)
{
httpHandler.Proxy = new WebProxy
{
- Address = new Uri($"{proxy.Host}:{proxy.Port}"),
- Credentials = proxy.Password == null ? null : new NetworkCredential(proxy.Login, proxy.Password)
+ Address = new Uri($"{options.Proxy.Host}:{options.Proxy.Port}"),
+ Credentials = options.Proxy.Password == null ? null : new NetworkCredential(options.Proxy.Login, options.Proxy.Password)
};
}
return httpHandler;
diff --git a/CryptoExchange.Net/Objects/Options/RestExchangeOptions.cs b/CryptoExchange.Net/Objects/Options/RestExchangeOptions.cs
index db4cd6e..d8694d6 100644
--- a/CryptoExchange.Net/Objects/Options/RestExchangeOptions.cs
+++ b/CryptoExchange.Net/Objects/Options/RestExchangeOptions.cs
@@ -32,10 +32,29 @@ namespace CryptoExchange.Net.Objects.Options
#else
= new Version(1, 1);
#endif
+
///
- /// Http client keep alive interval for keeping connections open
+ /// Http client keep alive interval for keeping connections open. Only applied when using dotnet8.0 or higher and dependency injection
///
public TimeSpan? HttpKeepAliveInterval { get; set; } = TimeSpan.FromSeconds(15);
+#if NET5_0_OR_GREATER
+ ///
+ /// Enable multiple simultaneous HTTP 2 connections. Only applied when using dependency injection
+ ///
+ public bool HttpEnableMultipleHttp2Connections { get; set; } = false;
+ ///
+ /// Lifetime of pooled HTTP connections; the time before a connection is recreated. Only applied when using dependency injection
+ ///
+ public TimeSpan HttpPooledConnectionLifetime { get; set; } = TimeSpan.FromMinutes(15);
+ ///
+ /// Idle timeout of pooled HTTP connections; the time before an open connection is closed when there are no requests. Only applied when using dependency injection
+ ///
+ public TimeSpan HttpPooledConnectionIdleTimeout { get; set; } = TimeSpan.FromMinutes(2);
+ ///
+ /// Max number of connections per server. Only applied when using dependency injection
+ ///
+ public int HttpMaxConnectionsPerServer { get; set; } = int.MaxValue;
+#endif
///
/// Set the values of this options on the target options
@@ -54,6 +73,12 @@ namespace CryptoExchange.Net.Objects.Options
item.CachingMaxAge = CachingMaxAge;
item.HttpVersion = HttpVersion;
item.HttpKeepAliveInterval = HttpKeepAliveInterval;
+#if NET5_0_OR_GREATER
+ item.HttpMaxConnectionsPerServer = HttpMaxConnectionsPerServer;
+ item.HttpPooledConnectionLifetime = HttpPooledConnectionLifetime;
+ item.HttpPooledConnectionIdleTimeout = HttpPooledConnectionIdleTimeout;
+ item.HttpEnableMultipleHttp2Connections = HttpEnableMultipleHttp2Connections;
+#endif
return item;
}
}
diff --git a/CryptoExchange.Net/Requests/RequestFactory.cs b/CryptoExchange.Net/Requests/RequestFactory.cs
index b70064e..f7ff553 100644
--- a/CryptoExchange.Net/Requests/RequestFactory.cs
+++ b/CryptoExchange.Net/Requests/RequestFactory.cs
@@ -12,14 +12,16 @@ namespace CryptoExchange.Net.Requests
public class RequestFactory : IRequestFactory
{
private HttpClient? _httpClient;
+ private RestExchangeOptions? _options;
///
public void Configure(RestExchangeOptions options, HttpClient? client = null)
{
if (client == null)
- client = CreateClient(options.Proxy, options.RequestTimeout, options.HttpKeepAliveInterval);
+ client = CreateClient(options);
_httpClient = client;
+ _options = options;
}
///
@@ -39,15 +41,20 @@ namespace CryptoExchange.Net.Requests
///
public void UpdateSettings(ApiProxy? proxy, TimeSpan requestTimeout, TimeSpan? httpKeepAliveInterval)
{
- _httpClient = CreateClient(proxy, requestTimeout, httpKeepAliveInterval);
+ var newOptions = new RestExchangeOptions();
+ _options!.Set(newOptions);
+ newOptions.Proxy = proxy;
+ newOptions.RequestTimeout = requestTimeout;
+ newOptions.HttpKeepAliveInterval = httpKeepAliveInterval;
+ _httpClient = CreateClient(newOptions);
}
- private static HttpClient CreateClient(ApiProxy? proxy, TimeSpan requestTimeout, TimeSpan? httpKeepAliveInterval)
+ private static HttpClient CreateClient(RestExchangeOptions options)
{
- var handler = LibraryHelpers.CreateHttpClientMessageHandler(proxy, httpKeepAliveInterval);
+ var handler = LibraryHelpers.CreateHttpClientMessageHandler(options);
var client = new HttpClient(handler)
{
- Timeout = requestTimeout
+ Timeout = options.RequestTimeout
};
return client;
}