1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-19 20:33:03 +00:00

Feature/9.0.0 (#236)

* Added support for Native AOT compilation
* Updated all IEnumerable response types to array response types
* Added Pass support for ApiCredentials, removing the need for most implementations to add their own ApiCredentials type
* Added KeepAliveTimeout setting setting ping frame timeouts for SocketApiClient
* Added IBookTickerRestClient Shared interface for requesting book tickers
* Added ISpotTriggerOrderRestClient Shared interface for managing spot trigger orders
* Added ISpotOrderClientIdClient Shared interface for managing spot orders by client order id
* Added IFuturesTriggerOrderRestClient Shared interface for managing futures trigger orders
* Added IFuturesOrderClientIdClient Shared interface for managing futures orders by client order id
* Added IFuturesTpSlRestClient Shared interface for setting TP/SL on open futures positions
* Added GenerateClientOrderId to ISpotOrderRestClient and IFuturesOrderRestClient interface
* Added OptionalExchangeParameters and Supported properties to EndpointOptions
* Refactor Shared interfaces quantity parameters and properties to use SharedQuantity
* Added SharedSymbol property to Shared interface models returning a symbol
* Added TriggerPrice, IsTriggerOrder, TakeProfitPrice, StopLossPrice and IsCloseOrder to SharedFuturesOrder response model
* Added MaxShortLeverage and MaxLongLeverage to SharedFuturesSymbol response model
* Added StopLossPrice and TakeProfitPrice to SharedPosition response model
* Added TriggerPrice and IsTriggerOrder to SharedSpotOrder response model
* Added QuoteVolume property to SharedSpotTicker response model
* Added AssetAlias configuration models
* Added static ExchangeSymbolCache for tracking symbol information from exchanges
* Added static CallResult.SuccessResult to be used instead of constructing success CallResult instance
* Added static ApplyRules, RandomHexString and RandomLong helper methods to ExchangeHelpers class
* Added AsErrorWithData To CallResult
* Added OriginalData property to CallResult
* Added support for adjusting the rate limit key per call, allowing for ratelimiting depending on request parameters
* Added implementation for integration testing ISymbolOrderBook instances
* Added implementation for integration testing socket subscriptions
* Added implementation for testing socket queries
* Updated request cancellation logging to Debug level
* Updated logging SourceContext to include the client type
* Updated some logging logic, errors no longer contain any data, exception are not logged as string but instead forwarded to structured logging
* Fixed warning for Enum parsing throwing exception and output warnings for each object in a response to only once to prevent slowing down execution
* Fixed memory leak in AsyncAutoRestEvent
* Fixed logging for ping frame timeout
* Fixed warning getting logged when user stops SymbolOrderBook instance
* Fixed socket client `UnsubscribeAll` not unsubscribing dedicated connections
* Fixed memory leak in Rest client cache
* Fixed integers bigger than int16 not getting correctly parsed to enums
* Fixed issue where the default options were overridden when using SetApiCredentials
* Removed Newtonsoft.Json dependency
* Removed legacy Rest client code
* Removed legacy ISpotClient and IFuturesClient support
This commit is contained in:
Jan Korf
2025-05-13 10:15:30 +02:00
committed by GitHub
parent 3d6267da93
commit 6b14cdbf06
182 changed files with 3159 additions and 3950 deletions
+19 -12
View File
@@ -1,9 +1,9 @@
using CryptoExchange.Net.Converters.JsonNet;
using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Logging.Extensions;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Objects.Options;
using CryptoExchange.Net.Objects.Sockets;
using CryptoExchange.Net.RateLimiting;
using CryptoExchange.Net.RateLimiting.Interfaces;
using CryptoExchange.Net.Sockets;
using Microsoft.Extensions.Logging;
@@ -42,6 +42,11 @@ namespace CryptoExchange.Net.Clients
/// </summary>
protected TimeSpan KeepAliveInterval { get; set; } = TimeSpan.FromSeconds(10);
/// <summary>
/// Keep alive timeout for websocket connection
/// </summary>
protected TimeSpan KeepAliveTimeout { get; set; } = TimeSpan.FromSeconds(10);
/// <summary>
/// Handlers for data from the socket which doesn't need to be forwarded to the caller. Ping or welcome messages for example.
/// </summary>
@@ -133,13 +138,13 @@ namespace CryptoExchange.Net.Clients
/// Create a message accessor instance
/// </summary>
/// <returns></returns>
protected internal virtual IByteMessageAccessor CreateAccessor() => new JsonNetByteMessageAccessor();
protected internal abstract IByteMessageAccessor CreateAccessor();
/// <summary>
/// Create a serializer instance
/// </summary>
/// <returns></returns>
protected internal virtual IMessageSerializer CreateSerializer() => new JsonNetMessageSerializer();
protected internal abstract IMessageSerializer CreateSerializer();
/// <summary>
/// Keep an open connection to this url
@@ -206,9 +211,9 @@ namespace CryptoExchange.Net.Clients
{
await semaphoreSlim.WaitAsync(ct).ConfigureAwait(false);
}
catch (OperationCanceledException)
catch (OperationCanceledException tce)
{
return new CallResult<UpdateSubscription>(new CancellationRequestedError());
return new CallResult<UpdateSubscription>(new CancellationRequestedError(tce));
}
try
@@ -378,7 +383,7 @@ namespace CryptoExchange.Net.Clients
protected virtual async Task<CallResult> ConnectIfNeededAsync(SocketConnection socket, bool authenticated)
{
if (socket.Connected)
return new CallResult(null);
return CallResult.SuccessResult;
var connectResult = await ConnectSocketAsync(socket).ConfigureAwait(false);
if (!connectResult)
@@ -388,7 +393,7 @@ namespace CryptoExchange.Net.Clients
await Task.Delay(ClientOptions.DelayAfterConnect).ConfigureAwait(false);
if (!authenticated || socket.Authenticated)
return new CallResult(null);
return CallResult.SuccessResult;
var result = await AuthenticateSocketAsync(socket).ConfigureAwait(false);
if (!result)
@@ -427,7 +432,7 @@ namespace CryptoExchange.Net.Clients
}
socket.Authenticated = true;
return new CallResult(null);
return CallResult.SuccessResult;
}
/// <summary>
@@ -475,7 +480,7 @@ namespace CryptoExchange.Net.Clients
/// <returns></returns>
protected internal virtual Task<CallResult> RevitalizeRequestAsync(Subscription subscription)
{
return Task.FromResult(new CallResult(null));
return Task.FromResult(CallResult.SuccessResult);
}
/// <summary>
@@ -561,11 +566,12 @@ namespace CryptoExchange.Net.Clients
/// </summary>
protected async virtual Task HandleConnectRateLimitedAsync()
{
if (ClientOptions.RateLimiterEnabled && RateLimiter is not null && ClientOptions.ConnectDelayAfterRateLimited is not null)
if (ClientOptions.RateLimiterEnabled && ClientOptions.ConnectDelayAfterRateLimited.HasValue)
{
var retryAfter = DateTime.UtcNow.Add(ClientOptions.ConnectDelayAfterRateLimited.Value);
_logger.AddingRetryAfterGuard(retryAfter);
await RateLimiter.SetRetryAfterGuardAsync(retryAfter, RateLimiting.RateLimitItemType.Connection).ConfigureAwait(false);
RateLimiter ??= new RateLimitGate("Connection");
await RateLimiter.SetRetryAfterGuardAsync(retryAfter, RateLimitItemType.Connection).ConfigureAwait(false);
}
}
@@ -596,6 +602,7 @@ namespace CryptoExchange.Net.Clients
=> new(new Uri(address), ClientOptions.ReconnectPolicy)
{
KeepAliveInterval = KeepAliveInterval,
KeepAliveTimeout = KeepAliveTimeout,
ReconnectInterval = ClientOptions.ReconnectInterval,
RateLimiter = ClientOptions.RateLimiterEnabled ? RateLimiter : null,
RateLimitingBehavior = ClientOptions.RateLimitingBehaviour,
@@ -712,7 +719,7 @@ namespace CryptoExchange.Net.Clients
return new CallResult(connectResult.Error!);
}
return new CallResult(null);
return CallResult.SuccessResult;
}
/// <inheritdoc />