1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-11 16:32:57 +00:00

Updated socket Subscription status handling, fixing timing issue for connection events and adding SubscriptionStatusChanged event

This commit is contained in:
Jkorf
2025-10-06 13:22:40 +02:00
parent da70ba6ec7
commit 1ece13f5bc
7 changed files with 134 additions and 49 deletions
+27
View File
@@ -267,4 +267,31 @@ namespace CryptoExchange.Net.Objects
Succeed
}
/// <summary>
/// Subscription status
/// </summary>
public enum SubscriptionStatus
{
/// <summary>
/// Pending, waiting before (re)subscription can be started
/// </summary>
Pending,
/// <summary>
/// Currently (re)subscribing, will start producing updates soon if subscription is successful
/// </summary>
Subscribing,
/// <summary>
/// Subscribed and listening to updates
/// </summary>
Subscribed,
/// <summary>
/// Subscription is being closed and will stop producing updates
/// </summary>
Closing,
/// <summary>
/// Subscription is closed and will no long produce updates
/// </summary>
Closed
}
}
@@ -15,6 +15,7 @@ namespace CryptoExchange.Net.Objects.Sockets
private readonly Subscription _listener;
private object _eventLock = new object();
private bool _connectionEventsSubscribed = true;
private List<Action> _connectionClosedEventHandlers = new List<Action>();
private List<Action> _connectionLostEventHandlers = new List<Action>();
private List<Action<Error>> _resubscribeFailedEventHandlers = new List<Action<Error>>();
@@ -22,6 +23,11 @@ namespace CryptoExchange.Net.Objects.Sockets
private List<Action> _activityPausedEventHandlers = new List<Action>();
private List<Action> _activityUnpausedEventHandlers = new List<Action>();
/// <summary>
/// Event when the status of the subscription changes
/// </summary>
public event Action<SubscriptionStatus>? SubscriptionStatusChanged;
/// <summary>
/// Event when the connection is lost. The socket will automatically reconnect when possible.
/// </summary>
@@ -113,21 +119,34 @@ namespace CryptoExchange.Net.Objects.Sockets
_connection.ActivityUnpaused += HandleUnpausedEvent;
_listener = subscription;
_listener.Unsubscribed += HandleUnsubscribed;
_listener.StatusChanged += (x) => SubscriptionStatusChanged?.Invoke(x);
}
private void HandleUnsubscribed()
private void UnsubscribeConnectionEvents()
{
_connection.ConnectionClosed -= HandleConnectionClosedEvent;
_connection.ConnectionLost -= HandleConnectionLostEvent;
_connection.ConnectionRestored -= HandleConnectionRestoredEvent;
_connection.ResubscribingFailed -= HandleResubscribeFailedEvent;
_connection.ActivityPaused -= HandlePausedEvent;
_connection.ActivityUnpaused -= HandleUnpausedEvent;
lock (_eventLock)
{
if (!_connectionEventsSubscribed)
return;
_connection.ConnectionClosed -= HandleConnectionClosedEvent;
_connection.ConnectionLost -= HandleConnectionLostEvent;
_connection.ConnectionRestored -= HandleConnectionRestoredEvent;
_connection.ResubscribingFailed -= HandleResubscribeFailedEvent;
_connection.ActivityPaused -= HandlePausedEvent;
_connection.ActivityUnpaused -= HandleUnpausedEvent;
_connectionEventsSubscribed = false;
}
}
private void HandleConnectionClosedEvent()
{
UnsubscribeConnectionEvents();
// If we're not the subscription closing this connection don't bother emitting
if (!_listener.IsClosingConnection)
return;
List<Action> handlers;
lock (_eventLock)
handlers = _connectionClosedEventHandlers.ToList();
@@ -138,6 +157,12 @@ namespace CryptoExchange.Net.Objects.Sockets
private void HandleConnectionLostEvent()
{
if (!_listener.Active)
{
UnsubscribeConnectionEvents();
return;
}
List<Action> handlers;
lock (_eventLock)
handlers = _connectionLostEventHandlers.ToList();
@@ -148,6 +173,12 @@ namespace CryptoExchange.Net.Objects.Sockets
private void HandleConnectionRestoredEvent(TimeSpan period)
{
if (!_listener.Active)
{
UnsubscribeConnectionEvents();
return;
}
List<Action<TimeSpan>> handlers;
lock (_eventLock)
handlers = _connectionRestoredEventHandlers.ToList();
@@ -158,6 +189,12 @@ namespace CryptoExchange.Net.Objects.Sockets
private void HandleResubscribeFailedEvent(Error error)
{
if (!_listener.Active)
{
UnsubscribeConnectionEvents();
return;
}
List<Action<Error>> handlers;
lock (_eventLock)
handlers = _resubscribeFailedEventHandlers.ToList();
@@ -168,6 +205,12 @@ namespace CryptoExchange.Net.Objects.Sockets
private void HandlePausedEvent()
{
if (!_listener.Active)
{
UnsubscribeConnectionEvents();
return;
}
List<Action> handlers;
lock (_eventLock)
handlers = _activityPausedEventHandlers.ToList();
@@ -178,6 +221,12 @@ namespace CryptoExchange.Net.Objects.Sockets
private void HandleUnpausedEvent()
{
if (!_listener.Active)
{
UnsubscribeConnectionEvents();
return;
}
List<Action> handlers;
lock (_eventLock)
handlers = _activityUnpausedEventHandlers.ToList();