diff --git a/src/Websocket.Client/DisconnectionType.cs b/src/Websocket.Client/DisconnectionType.cs
new file mode 100644
index 0000000..a0072e9
--- /dev/null
+++ b/src/Websocket.Client/DisconnectionType.cs
@@ -0,0 +1,33 @@
+namespace Websocket.Client
+{
+ ///
+ /// Type that specify happenend disconnection
+ ///
+ public enum DisconnectionType
+ {
+ ///
+ /// Type used for exit event, disposing of the websocket client
+ ///
+ Exit = 0,
+
+ ///
+ /// Type used when connection to websocket was lost in meantime
+ ///
+ Lost = 1,
+
+ ///
+ /// Type used when connection to websocket was lost by not receiving any message in given timerange
+ ///
+ NoMessageReceived = 2,
+
+ ///
+ /// Type used when connection or reconnection returned error
+ ///
+ Error = 3,
+
+ ///
+ /// Type used when disconnection was requested by user
+ ///
+ ByUser = 4
+ }
+}
diff --git a/src/Websocket.Client/IWebsocketClient.cs b/src/Websocket.Client/IWebsocketClient.cs
index dc39c3c..4c7cd03 100644
--- a/src/Websocket.Client/IWebsocketClient.cs
+++ b/src/Websocket.Client/IWebsocketClient.cs
@@ -18,6 +18,11 @@ public interface IWebsocketClient : IDisposable
///
IObservable ReconnectionHappened { get; }
+ ///
+ /// Stream for disconnection event (trigerred after the connection was lost)
+ ///
+ IObservable DisconnectionHappened { get; }
+
///
/// Time range in ms, how long to wait before reconnecting if no message comes from server.
/// Default 60000 ms (1 minute)
diff --git a/src/Websocket.Client/ReconnectionType.cs b/src/Websocket.Client/ReconnectionType.cs
index 649c7b0..c6fd9c8 100644
--- a/src/Websocket.Client/ReconnectionType.cs
+++ b/src/Websocket.Client/ReconnectionType.cs
@@ -1,30 +1,33 @@
namespace Websocket.Client
{
+ ///
+ /// Type that specify happenend reconnection
+ ///
public enum ReconnectionType
{
///
/// Type used for initial connection to websocket stream
///
- Initial,
+ Initial = 0,
///
/// Type used when connection to websocket was lost in meantime
///
- Lost,
+ Lost = 1,
///
/// Type used when connection to websocket was lost by not receiving any message in given timerange
///
- NoMessageReceived,
+ NoMessageReceived = 2,
///
/// Type used after unsuccessful previous reconnection
///
- Error,
+ Error = 3,
///
/// Type used when reconnection was requested by user
///
- ByUser
+ ByUser = 4
}
}
diff --git a/src/Websocket.Client/WebsocketClient.cs b/src/Websocket.Client/WebsocketClient.cs
index c3a5ce2..aecf2a5 100644
--- a/src/Websocket.Client/WebsocketClient.cs
+++ b/src/Websocket.Client/WebsocketClient.cs
@@ -28,6 +28,7 @@ public class WebsocketClient : IWebsocketClient
private readonly Subject _messageReceivedSubject = new Subject();
private readonly Subject _reconnectionSubject = new Subject();
+ private readonly Subject _disconnectedSubject = new Subject();
private readonly BlockingCollection _messagesToSendQueue = new BlockingCollection();
@@ -53,6 +54,11 @@ public WebsocketClient(Uri url, Func clientFactory = null)
///
public IObservable ReconnectionHappened => _reconnectionSubject.AsObservable();
+ ///
+ /// Stream for disconnection event (trigerred after the connection was lost)
+ ///
+ public IObservable DisconnectionHappened => _disconnectedSubject.AsObservable();
+
///
/// Time range in ms, how long to wait before reconnecting if no message comes from server.
/// Default 60000 ms (1 minute)
@@ -82,15 +88,24 @@ public void Dispose()
{
_disposing = true;
Log.Debug(L("Disposing.."));
- _lastChanceTimer?.Dispose();
- _cancelation?.Cancel();
- _cancelationTotal?.Cancel();
- _client?.Abort();
- _client?.Dispose();
- _cancelation?.Dispose();
- _cancelationTotal?.Dispose();
- _messagesToSendQueue?.Dispose();
+ try
+ {
+ _lastChanceTimer?.Dispose();
+ _cancelation?.Cancel();
+ _cancelationTotal?.Cancel();
+ _client?.Abort();
+ _client?.Dispose();
+ _cancelation?.Dispose();
+ _cancelationTotal?.Dispose();
+ _messagesToSendQueue?.Dispose();
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, L($"Failed to dispose client, error: {e.Message}"));
+ }
+
IsStarted = false;
+ _disconnectedSubject.OnNext(DisconnectionType.Exit);
}
///
@@ -161,7 +176,14 @@ private async Task SendFromQueue()
{
foreach (var message in _messagesToSendQueue.GetConsumingEnumerable(_cancelationTotal.Token))
{
- await SendInternal(message).ConfigureAwait(false);
+ try
+ {
+ await SendInternal(message).ConfigureAwait(false);
+ }
+ catch (Exception e)
+ {
+ Log.Error(L($"Failed to send message: '{message}'. Error: {e.Message}"));
+ }
}
}
catch (TaskCanceledException)
@@ -214,6 +236,7 @@ private async Task StartClient(Uri uri, CancellationToken token, ReconnectionTyp
}
catch (Exception e)
{
+ _disconnectedSubject.OnNext(DisconnectionType.Error);
Log.Error(e, L("Exception while connecting. " +
$"Waiting {ErrorReconnectTimeoutMs/1000} sec before next reconnection try."));
await Task.Delay(ErrorReconnectTimeoutMs, token).ConfigureAwait(false);
@@ -230,11 +253,14 @@ private async Task GetClient()
return _client;
}
- private async Task Reconnect( ReconnectionType type)
+ private async Task Reconnect(ReconnectionType type)
{
IsRunning = false;
if (_disposing)
return;
+ if(type != ReconnectionType.Error)
+ _disconnectedSubject.OnNext(TranslateTypeToDisconnection(type));
+
Log.Debug(L("Reconnecting..."));
_cancelation.Cancel();
await Task.Delay(1000).ConfigureAwait(false);
@@ -313,5 +339,11 @@ private string L(string msg)
{
return $"[WEBSOCKET CLIENT] {msg}";
}
+
+ private DisconnectionType TranslateTypeToDisconnection(ReconnectionType type)
+ {
+ // beaware enum indexes must correspond to each other
+ return (DisconnectionType) type;
+ }
}
}
diff --git a/test_integration/Websocket.Client.Sample/Program.cs b/test_integration/Websocket.Client.Sample/Program.cs
index 70f8ceb..de6c311 100644
--- a/test_integration/Websocket.Client.Sample/Program.cs
+++ b/test_integration/Websocket.Client.Sample/Program.cs
@@ -38,10 +38,12 @@ static void Main(string[] args)
client.ReconnectTimeoutMs = (int)TimeSpan.FromSeconds(30).TotalMilliseconds;
client.ReconnectionHappened.Subscribe(type =>
Log.Information($"Reconnection happened, type: {type}"));
+ client.DisconnectionHappened.Subscribe(type =>
+ Log.Warning($"Disconnection happened, type: {type}"));
client.MessageReceived.Subscribe(msg => Log.Information($"Message received: {msg}"));
- client.Start();
+ client.Start().Wait();
Task.Run(() => StartSendingPing(client));