mirror of
https://github.com/JKorf/CryptoExchange.Net.git
synced 2026-08-15 02:13:01 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f2cf70b02f | |||
| 9ff417bba8 | |||
| 6b43d08a4d | |||
| 39bf7fe9b9 | |||
| b5893c3b60 |
@@ -72,6 +72,11 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected List<DedicatedConnectionConfig> DedicatedConnectionConfigs { get; set; } = new List<DedicatedConnectionConfig>();
|
protected List<DedicatedConnectionConfig> DedicatedConnectionConfigs { get; set; } = new List<DedicatedConnectionConfig>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to allow multiple subscriptions with the same topic on the same connection
|
||||||
|
/// </summary>
|
||||||
|
protected bool AllowTopicsOnTheSameConnection { get; set; } = true;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public double IncomingKbps
|
public double IncomingKbps
|
||||||
{
|
{
|
||||||
@@ -211,7 +216,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// Get a new or existing socket connection
|
// Get a new or existing socket connection
|
||||||
var socketResult = await GetSocketConnection(url, subscription.Authenticated, false).ConfigureAwait(false);
|
var socketResult = await GetSocketConnection(url, subscription.Authenticated, false, subscription.Topic).ConfigureAwait(false);
|
||||||
if (!socketResult)
|
if (!socketResult)
|
||||||
return socketResult.As<UpdateSubscription>(null);
|
return socketResult.As<UpdateSubscription>(null);
|
||||||
|
|
||||||
@@ -403,7 +408,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
return new CallResult(new NoApiCredentialsError());
|
return new CallResult(new NoApiCredentialsError());
|
||||||
|
|
||||||
_logger.AttemptingToAuthenticate(socket.SocketId);
|
_logger.AttemptingToAuthenticate(socket.SocketId);
|
||||||
var authRequest = GetAuthenticationRequest(socket);
|
var authRequest = await GetAuthenticationRequestAsync(socket).ConfigureAwait(false);
|
||||||
if (authRequest != null)
|
if (authRequest != null)
|
||||||
{
|
{
|
||||||
var result = await socket.SendAndWaitQueryAsync(authRequest).ConfigureAwait(false);
|
var result = await socket.SendAndWaitQueryAsync(authRequest).ConfigureAwait(false);
|
||||||
@@ -428,7 +433,7 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// Should return the request which can be used to authenticate a socket connection
|
/// Should return the request which can be used to authenticate a socket connection
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected internal virtual Query? GetAuthenticationRequest(SocketConnection connection) => throw new NotImplementedException();
|
protected internal virtual Task<Query?> GetAuthenticationRequestAsync(SocketConnection connection) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a system subscription. Used for example to reply to ping requests
|
/// Adds a system subscription. Used for example to reply to ping requests
|
||||||
@@ -478,13 +483,15 @@ namespace CryptoExchange.Net.Clients
|
|||||||
/// <param name="address">The address the socket is for</param>
|
/// <param name="address">The address the socket is for</param>
|
||||||
/// <param name="authenticated">Whether the socket should be authenticated</param>
|
/// <param name="authenticated">Whether the socket should be authenticated</param>
|
||||||
/// <param name="dedicatedRequestConnection">Whether a dedicated request connection should be returned</param>
|
/// <param name="dedicatedRequestConnection">Whether a dedicated request connection should be returned</param>
|
||||||
|
/// <param name="topic">The subscription topic, can be provided when multiple of the same topics are not allowed on a connection</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected virtual async Task<CallResult<SocketConnection>> GetSocketConnection(string address, bool authenticated, bool dedicatedRequestConnection)
|
protected virtual async Task<CallResult<SocketConnection>> GetSocketConnection(string address, bool authenticated, bool dedicatedRequestConnection, string? topic = null)
|
||||||
{
|
{
|
||||||
var socketQuery = socketConnections.Where(s => (s.Value.Status == SocketConnection.SocketStatus.None || s.Value.Status == SocketConnection.SocketStatus.Connected)
|
var socketQuery = socketConnections.Where(s => (s.Value.Status == SocketConnection.SocketStatus.None || s.Value.Status == SocketConnection.SocketStatus.Connected)
|
||||||
&& s.Value.Tag.TrimEnd('/') == address.TrimEnd('/')
|
&& s.Value.Tag.TrimEnd('/') == address.TrimEnd('/')
|
||||||
&& s.Value.ApiClient.GetType() == GetType()
|
&& s.Value.ApiClient.GetType() == GetType()
|
||||||
&& (s.Value.Authenticated == authenticated || !authenticated)
|
&& (s.Value.Authenticated == authenticated || !authenticated)
|
||||||
|
&& (AllowTopicsOnTheSameConnection || !s.Value.Topics.Contains(topic))
|
||||||
&& s.Value.Connected);
|
&& s.Value.Connected);
|
||||||
|
|
||||||
SocketConnection connection;
|
SocketConnection connection;
|
||||||
|
|||||||
@@ -126,7 +126,14 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
return default;
|
return default;
|
||||||
|
|
||||||
if (value.Value.ValueKind == JsonValueKind.Object || value.Value.ValueKind == JsonValueKind.Array)
|
if (value.Value.ValueKind == JsonValueKind.Object || value.Value.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return value.Value.Deserialize<T>(_serializerOptions);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
return default;
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof(T) == typeof(string))
|
if (typeof(T) == typeof(string))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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>8.1.1</PackageVersion>
|
<PackageVersion>8.2.0</PackageVersion>
|
||||||
<AssemblyVersion>8.1.1</AssemblyVersion>
|
<AssemblyVersion>8.2.0</AssemblyVersion>
|
||||||
<FileVersion>8.1.1</FileVersion>
|
<FileVersion>8.2.0</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>
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Leverage is configured for the symbol
|
/// Leverage is configured for the symbol
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PerSymbol
|
PerSymbol,
|
||||||
|
/// <summary>
|
||||||
|
/// Leverage is configured for the entire account
|
||||||
|
/// </summary>
|
||||||
|
PerAccount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Side of the trade
|
/// Side of the trade
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SharedOrderSide Side { get; set; }
|
public SharedOrderSide? Side { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fee paid for the trade
|
/// Fee paid for the trade
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -51,7 +51,7 @@ namespace CryptoExchange.Net.SharedApis
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SharedUserTrade(string symbol, string orderId, string id, SharedOrderSide side, decimal quantity, decimal price, DateTime timestamp)
|
public SharedUserTrade(string symbol, string orderId, string id, SharedOrderSide? side, decimal quantity, decimal price, DateTime timestamp)
|
||||||
{
|
{
|
||||||
Symbol = symbol;
|
Symbol = symbol;
|
||||||
OrderId = orderId;
|
OrderId = orderId;
|
||||||
|
|||||||
@@ -190,6 +190,18 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DedicatedConnectionState DedicatedRequestConnection { get; internal set; } = new DedicatedConnectionState();
|
public DedicatedConnectionState DedicatedRequestConnection { get; internal set; } = new DedicatedConnectionState();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Current subscription topics on this connection
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<string> Topics
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_listenersLock)
|
||||||
|
return _listeners.OfType<Subscription>().Select(x => x.Topic).Where(t => t != null).ToList()!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool _pausedActivity;
|
private bool _pausedActivity;
|
||||||
private readonly object _listenersLock;
|
private readonly object _listenersLock;
|
||||||
private readonly List<IMessageProcessor> _listeners;
|
private readonly List<IMessageProcessor> _listeners;
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public abstract Type? GetMessageType(IMessageAccessor message);
|
public abstract Type? GetMessageType(IMessageAccessor message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subscription topic
|
||||||
|
/// </summary>
|
||||||
|
public string? Topic { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ 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 8.2.0 - 06 Nov 2024
|
||||||
|
* Added support for not allowing duplicate subscription topics on the same websocket connection
|
||||||
|
* Added PerAccount SharedLeverageSettingMode enum value, changed Side on SharedUserTrade to nullable
|
||||||
|
* Added support for object deserialization in SystemTextJsonMessageAccessor.GetValue<T>
|
||||||
|
* Changed SocketApiClient GetAuthenticationRequest to GetAuthenticationRequestAsync to allow for requesting token
|
||||||
|
|
||||||
* Version 8.1.1 - 01 Nov 2024
|
* Version 8.1.1 - 01 Nov 2024
|
||||||
* Fixed socket connections trying to authenticated connection when it's marked as dedicated request connection even when no authentication is needed
|
* Fixed socket connections trying to authenticated connection when it's marked as dedicated request connection even when no authentication is needed
|
||||||
* Fixed System.Text.Json ArrayConverter not passing serializer options to nested deserialization
|
* Fixed System.Text.Json ArrayConverter not passing serializer options to nested deserialization
|
||||||
|
|||||||
Reference in New Issue
Block a user