mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-09-03 06:01:40 +00:00
Compare commits
3 Commits
2fde9a285e
...
f739520e52
Author | SHA1 | Date | |
---|---|---|---|
|
f739520e52 | ||
|
0152603ddb | ||
|
aa06e0eead |
@ -82,6 +82,11 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool AllowTopicsOnTheSameConnection { get; set; } = true;
|
protected bool AllowTopicsOnTheSameConnection { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to continue processing and forward unparsable messages to handlers
|
||||||
|
/// </summary>
|
||||||
|
protected internal bool ProcessUnparsableMessages { get; set; } = false;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public double IncomingKbps
|
public double IncomingKbps
|
||||||
{
|
{
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
<PackageId>CryptoExchange.Net</PackageId>
|
<PackageId>CryptoExchange.Net</PackageId>
|
||||||
<Authors>JKorf</Authors>
|
<Authors>JKorf</Authors>
|
||||||
<Description>CryptoExchange.Net is a base library which is used to implement different cryptocurrency (exchange) API's. It provides a standardized way of implementing different API's, which results in a very similar experience for users of the API implementations.</Description>
|
<Description>CryptoExchange.Net is a base library which is used to implement different cryptocurrency (exchange) API's. It provides a standardized way of implementing different API's, which results in a very similar experience for users of the API implementations.</Description>
|
||||||
<PackageVersion>9.2.0</PackageVersion>
|
<PackageVersion>9.2.1</PackageVersion>
|
||||||
<AssemblyVersion>9.2.0</AssemblyVersion>
|
<AssemblyVersion>9.2.1</AssemblyVersion>
|
||||||
<FileVersion>9.2.0</FileVersion>
|
<FileVersion>9.2.1</FileVersion>
|
||||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||||
<PackageTags>OKX;OKX.Net;Mexc;Mexc.Net;Kucoin;Kucoin.Net;Kraken;Kraken.Net;Huobi;Huobi.Net;CoinEx;CoinEx.Net;Bybit;Bybit.Net;Bitget;Bitget.Net;Bitfinex;Bitfinex.Net;Binance;Binance.Net;CryptoCurrency;CryptoCurrency Exchange</PackageTags>
|
<PackageTags>OKX;OKX.Net;Mexc;Mexc.Net;Kucoin;Kucoin.Net;Kraken;Kraken.Net;Huobi;Huobi.Net;CoinEx;CoinEx.Net;Bybit;Bybit.Net;Bitget;Bitget.Net;Bitfinex;Bitfinex.Net;Binance;Binance.Net;CryptoCurrency;CryptoCurrency Exchange</PackageTags>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
|
@ -11,8 +11,6 @@ using System.Diagnostics;
|
|||||||
using CryptoExchange.Net.Clients;
|
using CryptoExchange.Net.Clients;
|
||||||
using CryptoExchange.Net.Logging.Extensions;
|
using CryptoExchange.Net.Logging.Extensions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using CryptoExchange.Net.Objects.Options;
|
|
||||||
using CryptoExchange.Net.Authentication;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Sockets
|
namespace CryptoExchange.Net.Sockets
|
||||||
{
|
{
|
||||||
@ -475,7 +473,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
_logger.ReceivedData(SocketId, originalData);
|
_logger.ReceivedData(SocketId, originalData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!accessor.IsValid)
|
if (!accessor.IsValid && !ApiClient.ProcessUnparsableMessages)
|
||||||
{
|
{
|
||||||
_logger.FailedToParse(SocketId, result.Error!.Message);
|
_logger.FailedToParse(SocketId, result.Error!.Message);
|
||||||
return;
|
return;
|
||||||
|
@ -176,18 +176,32 @@ namespace CryptoExchange.Net.Trackers.Klines
|
|||||||
Status = SyncStatus.Syncing;
|
Status = SyncStatus.Syncing;
|
||||||
_logger.KlineTrackerStarting(SymbolName);
|
_logger.KlineTrackerStarting(SymbolName);
|
||||||
|
|
||||||
var startResult = await DoStartAsync().ConfigureAwait(false);
|
var subResult = await _socketClient.SubscribeToKlineUpdatesAsync(new SubscribeKlineRequest(Symbol, _interval),
|
||||||
if (!startResult)
|
update =>
|
||||||
|
{
|
||||||
|
AddOrUpdate(update.Data);
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!subResult)
|
||||||
{
|
{
|
||||||
_logger.KlineTrackerStartFailed(SymbolName, startResult.Error!.Message, startResult.Error.Exception);
|
_logger.KlineTrackerStartFailed(SymbolName, subResult.Error!.Message, subResult.Error.Exception);
|
||||||
Status = SyncStatus.Disconnected;
|
Status = SyncStatus.Disconnected;
|
||||||
return new CallResult(startResult.Error!);
|
return subResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateSubscription = startResult.Data;
|
_updateSubscription = subResult.Data;
|
||||||
_updateSubscription.ConnectionLost += HandleConnectionLost;
|
_updateSubscription.ConnectionLost += HandleConnectionLost;
|
||||||
_updateSubscription.ConnectionClosed += HandleConnectionClosed;
|
_updateSubscription.ConnectionClosed += HandleConnectionClosed;
|
||||||
_updateSubscription.ConnectionRestored += HandleConnectionRestored;
|
_updateSubscription.ConnectionRestored += HandleConnectionRestored;
|
||||||
|
|
||||||
|
var startResult = await DoStartAsync().ConfigureAwait(false);
|
||||||
|
if (!startResult)
|
||||||
|
{
|
||||||
|
_ = subResult.Data.CloseAsync();
|
||||||
|
Status = SyncStatus.Disconnected;
|
||||||
|
return new CallResult(startResult.Error!);
|
||||||
|
}
|
||||||
|
|
||||||
Status = SyncStatus.Synced;
|
Status = SyncStatus.Synced;
|
||||||
_logger.KlineTrackerStarted(SymbolName);
|
_logger.KlineTrackerStarted(SymbolName);
|
||||||
return CallResult.SuccessResult;
|
return CallResult.SuccessResult;
|
||||||
@ -208,22 +222,10 @@ namespace CryptoExchange.Net.Trackers.Klines
|
|||||||
/// The start procedure needed for kline syncing, generally subscribing to an update stream and requesting the snapshot
|
/// The start procedure needed for kline syncing, generally subscribing to an update stream and requesting the snapshot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected virtual async Task<CallResult<UpdateSubscription>> DoStartAsync()
|
protected virtual async Task<CallResult> DoStartAsync()
|
||||||
{
|
{
|
||||||
var subResult = await _socketClient.SubscribeToKlineUpdatesAsync(new SubscribeKlineRequest(Symbol, _interval),
|
|
||||||
update =>
|
|
||||||
{
|
|
||||||
AddOrUpdate(update.Data);
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (!subResult)
|
|
||||||
{
|
|
||||||
Status = SyncStatus.Disconnected;
|
|
||||||
return subResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_startWithSnapshot)
|
if (!_startWithSnapshot)
|
||||||
return subResult;
|
return CallResult.SuccessResult;
|
||||||
|
|
||||||
var startTime = Period == null ? (DateTime?)null : DateTime.UtcNow.Add(-Period.Value);
|
var startTime = Period == null ? (DateTime?)null : DateTime.UtcNow.Add(-Period.Value);
|
||||||
if (_restClient.GetKlinesOptions.MaxAge != null && DateTime.UtcNow.Add(-_restClient.GetKlinesOptions.MaxAge.Value) > startTime)
|
if (_restClient.GetKlinesOptions.MaxAge != null && DateTime.UtcNow.Add(-_restClient.GetKlinesOptions.MaxAge.Value) > startTime)
|
||||||
@ -236,11 +238,7 @@ namespace CryptoExchange.Net.Trackers.Klines
|
|||||||
await foreach (var result in ExchangeHelpers.ExecutePages(_restClient.GetKlinesAsync, request).ConfigureAwait(false))
|
await foreach (var result in ExchangeHelpers.ExecutePages(_restClient.GetKlinesAsync, request).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
return result;
|
||||||
_ = subResult.Data.CloseAsync();
|
|
||||||
Status = SyncStatus.Disconnected;
|
|
||||||
return subResult.AsError<UpdateSubscription>(result.Error!);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Limit != null && data.Count > Limit)
|
if (Limit != null && data.Count > Limit)
|
||||||
break;
|
break;
|
||||||
@ -249,7 +247,7 @@ namespace CryptoExchange.Net.Trackers.Klines
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetInitialData(data);
|
SetInitialData(data);
|
||||||
return subResult;
|
return CallResult.SuccessResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -199,7 +199,12 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
_startWithSnapshot = startWithSnapshot;
|
_startWithSnapshot = startWithSnapshot;
|
||||||
Status = SyncStatus.Syncing;
|
Status = SyncStatus.Syncing;
|
||||||
_logger.TradeTrackerStarting(SymbolName);
|
_logger.TradeTrackerStarting(SymbolName);
|
||||||
var subResult = await DoStartAsync().ConfigureAwait(false);
|
var subResult = await _socketClient.SubscribeToTradeUpdatesAsync(new SubscribeTradeRequest(Symbol),
|
||||||
|
update =>
|
||||||
|
{
|
||||||
|
AddData(update.Data);
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
if (!subResult)
|
if (!subResult)
|
||||||
{
|
{
|
||||||
_logger.TradeTrackerStartFailed(SymbolName, subResult.Error!.Message, subResult.Error.Exception);
|
_logger.TradeTrackerStartFailed(SymbolName, subResult.Error!.Message, subResult.Error.Exception);
|
||||||
@ -211,6 +216,15 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
_updateSubscription.ConnectionLost += HandleConnectionLost;
|
_updateSubscription.ConnectionLost += HandleConnectionLost;
|
||||||
_updateSubscription.ConnectionClosed += HandleConnectionClosed;
|
_updateSubscription.ConnectionClosed += HandleConnectionClosed;
|
||||||
_updateSubscription.ConnectionRestored += HandleConnectionRestored;
|
_updateSubscription.ConnectionRestored += HandleConnectionRestored;
|
||||||
|
|
||||||
|
var result = await DoStartAsync().ConfigureAwait(false);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
_ = subResult.Data.CloseAsync();
|
||||||
|
Status = SyncStatus.Disconnected;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
SetSyncStatus();
|
SetSyncStatus();
|
||||||
_logger.TradeTrackerStarted(SymbolName);
|
_logger.TradeTrackerStarted(SymbolName);
|
||||||
return CallResult.SuccessResult;
|
return CallResult.SuccessResult;
|
||||||
@ -231,22 +245,10 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
/// The start procedure needed for trade syncing, generally subscribing to an update stream and requesting the snapshot
|
/// The start procedure needed for trade syncing, generally subscribing to an update stream and requesting the snapshot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected virtual async Task<CallResult<UpdateSubscription>> DoStartAsync()
|
protected virtual async Task<CallResult> DoStartAsync()
|
||||||
{
|
{
|
||||||
var subResult = await _socketClient.SubscribeToTradeUpdatesAsync(new SubscribeTradeRequest(Symbol),
|
|
||||||
update =>
|
|
||||||
{
|
|
||||||
AddData(update.Data);
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (!subResult)
|
|
||||||
{
|
|
||||||
Status = SyncStatus.Disconnected;
|
|
||||||
return subResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_startWithSnapshot)
|
if (!_startWithSnapshot)
|
||||||
return subResult;
|
return CallResult.SuccessResult;
|
||||||
|
|
||||||
if (_historyRestClient != null)
|
if (_historyRestClient != null)
|
||||||
{
|
{
|
||||||
@ -256,12 +258,8 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
await foreach(var result in ExchangeHelpers.ExecutePages(_historyRestClient.GetTradeHistoryAsync, request).ConfigureAwait(false))
|
await foreach(var result in ExchangeHelpers.ExecutePages(_historyRestClient.GetTradeHistoryAsync, request).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
return result;
|
||||||
_ = subResult.Data.CloseAsync();
|
|
||||||
Status = SyncStatus.Disconnected;
|
|
||||||
return subResult.AsError<UpdateSubscription>(result.Error!);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Limit != null && data.Count > Limit)
|
if (Limit != null && data.Count > Limit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -279,15 +277,13 @@ namespace CryptoExchange.Net.Trackers.Trades
|
|||||||
var snapshot = await _recentRestClient.GetRecentTradesAsync(new GetRecentTradesRequest(Symbol, limit)).ConfigureAwait(false);
|
var snapshot = await _recentRestClient.GetRecentTradesAsync(new GetRecentTradesRequest(Symbol, limit)).ConfigureAwait(false);
|
||||||
if (!snapshot)
|
if (!snapshot)
|
||||||
{
|
{
|
||||||
_ = subResult.Data.CloseAsync();
|
return snapshot;
|
||||||
Status = SyncStatus.Disconnected;
|
|
||||||
return subResult.AsError<UpdateSubscription>(snapshot.Error!);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetInitialData(snapshot.Data);
|
SetInitialData(snapshot.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return subResult;
|
return CallResult.SuccessResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -58,6 +58,10 @@ Make a one time donation in a crypto currency of your choice. If you prefer to d
|
|||||||
Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf).
|
Alternatively, sponsor me on Github using [Github Sponsors](https://github.com/sponsors/JKorf).
|
||||||
|
|
||||||
## Release notes
|
## Release notes
|
||||||
|
* Version 9.2.1 - 16 Jul 2025
|
||||||
|
* Added setting for whether or not to process unparsable websocket messages
|
||||||
|
* Fixed issue causing duplicate subscriptions and data in the TradeTracker and KlineTracker when websocket connection was reconnected
|
||||||
|
|
||||||
* Version 9.2.0 - 14 Jul 2025
|
* Version 9.2.0 - 14 Jul 2025
|
||||||
* Added support for sending byte data on websocket
|
* Added support for sending byte data on websocket
|
||||||
* Added support for handling both string and byte data with different IMessageAccessor types
|
* Added support for handling both string and byte data with different IMessageAccessor types
|
||||||
|
Loading…
x
Reference in New Issue
Block a user