Closed brooksyott closed 7 years ago
Thank you for raising this. The documentation is not clear on this and I will update it.
What you need to do is to listen for the exception in your subscription. Like this:
_subscribeToMessagesReceived = websocketClient.ObserveTextMessagesReceived.Subscribe(
msg =>
{
System.Console.WriteLine($"Reply from test server: {msg}");
},
ex =>
{
System.Console.WriteLine(ex.Message);
},
() =>
{
System.Console.WriteLine($"Subscription Completed");
});
In the above the subscription listens to three things:
This is the pattern used with Rx.
Please let me know if this helps?
It was very helpful, thank you. The exception does come now, terrific. If I leave the network disconnected what I see is:
It seems to work, but it's not pretty :).
Again, thank you so much for the quick reply today. It definitely helped
Great to hear.
What you describe makes perfect sense.
When the connection fails you need to re-connect it before you try sending something new. Not sure you need to create a new instance of the MessageWebSocketRx object.
From the moment the connection fails to you receive an exception via Rx there is a time gap. In mine testing it was 20 seconds. This makes sense as the client don't know that the connection is gone. It has to timeout first.
Regarding looking pretty. I would it something like this:
static void Main(string[] args)
{
var outerCancellationSource = new CancellationTokenSource();
Task.Run(() => StartWebSocketAsyncWithRetry(outerCancellationSource), outerCancellationSource.Token);
System.Console.WriteLine("Waiting...");
System.Console.ReadKey();
outerCancellationSource.Cancel();
_subscribeToMessagesReceived.Dispose();
}
private static async Task StartWebSocketAsyncWithRetry(CancellationTokenSource outerCancellationTokenSource)
{
while (!outerCancellationTokenSource.IsCancellationRequested)
{
var innerCancellationSource = new CancellationTokenSource();
await StartWebSocketAsync(innerCancellationSource);
while (!innerCancellationSource.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(10), innerCancellationSource.Token);
}
// Wait 5 seconds before trying again
await Task.Delay(TimeSpan.FromSeconds(5), outerCancellationTokenSource.Token);
}
}
private static async Task StartWebSocketAsync(CancellationTokenSource innerCancellationTokenSource)
{
using (var websocketClient = new MessageWebSocketRx())
{
_subscribeToMessagesReceived = websocketClient.ObserveTextMessagesReceived.Subscribe(
msg =>
{
// Msg receive code goes here
},
ex =>
{
// Cancel the inner loop when exception
innerCancellationTokenSource.Cancel();
},
() =>
{
// Cancel the inner loop when complete
innerCancellationTokenSource.Cancel();
});
....
See example here
Hello,
So far, I'm liking this library a lot. A major issue I have though at the moment is when a connection to the internet is lost, or the far end drops the connection, I get an exception when I use SendTextAsync(String). It appears I can't catch the exception (or so far I haven't been able to). Any ideas how to work around this issue? To reproduce this, I simply disable my internet connection while sending messages
The exception I get is:
System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult) --- End of inner exception stack trace --- at System.Net.Security._SslStream.EndRead(IAsyncResult asyncResult) at System.Net.Security.SslStream.EndRead(IAsyncResult asyncResult) at System.IO.Stream.<>c.b43_1(Stream stream, IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactoryb__271(Exception ex)
at System.Reactive.AnonymousSafeObserverb 72_0(Actionb0(Object arg)
at System.Reactive.Concurrency.ConcurrencyAbstractionLayerImpl.<>cDisplayClass7_0.b__0()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
1.FromAsyncTrimPromise
1.Complete(TInstance thisRef, Func3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at WebsocketClientLite.PCL.Service.WebsocketListener.<ReadOneByteAtTheTimeAsync>d__26.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Reactive.PlatformServices.ExceptionServicesImpl.Rethrow(Exception exception) at System.Reactive.Stubs.<>c.<.cctor>b__2_1(Exception ex) at System.Reactive.AnonymousSafeObserver
1.OnError(Exception error) at System.Reactive.Linq.ObservableImpl.AsObservable1._.OnError(Exception error) at System.Reactive.Subjects.Subject
1.OnError(Exception error) at WebsocketClientLite.PCL.Service.WebsocketListener.1.OnError(Exception error) at System.Reactive.Linq.ObservableImpl.Where
1..OnError(Exception error) at System.Reactive.Linq.ObservableImpl.Select2._.OnError(Exception error) at System.Reactive.ScheduledObserver
1.Dispatch(ICancelable cancel) at System.Reactive.Concurrency.Scheduler.<>c.1 a, ICancelable c) at System.Reactive.Concurrency.DefaultScheduler.LongRunning.<>c__DisplayClass1_0
1.