Skip to content
This repository has been archived by the owner on Jul 21, 2022. It is now read-only.

Commit

Permalink
Fails more nicely.
Browse files Browse the repository at this point in the history
If the connection is aborted, an ExceptionOccured event is raised on
Pusher. When you receive this event, Pusher.NET has given up on
reconnecting, and it is no longer connected. Handle it as you wish.
  • Loading branch information
vegardlarsen committed Feb 13, 2014
1 parent e2c31ec commit 3af05e6
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 13 deletions.
35 changes: 33 additions & 2 deletions Pusher.Connections.Net/WebSocketConnection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Pusher.Events;
using WebSocket4Net;
using DataReceivedEventArgs = Pusher.Events.DataReceivedEventArgs;

Expand Down Expand Up @@ -39,7 +40,18 @@ private async void OnMessageReceived(object sender, MessageReceivedEventArgs arg
exceptionOccured = true;
}
// cannot await in catch
if (exceptionOccured) await Reconnect();
if (exceptionOccured)
{
_connectionState = ConnectionState.Failed;
try
{
await Reconnect();
}
catch (Exception e)
{
Error(e);
}
}
}

private async Task Reconnect()
Expand All @@ -54,7 +66,16 @@ private async void OnSocketClosed(object sender, EventArgs args)
{
if (_connectionState != ConnectionState.Disconnecting)
{
await Reconnect();
_connectionState = ConnectionState.Failed;
try
{
await Reconnect();
}
catch (Exception e)
{
Error(e);
return;
}
}
_connectionState = ConnectionState.Disconnected;
if (OnClose != null) OnClose(sender, new EventArgs());
Expand Down Expand Up @@ -97,6 +118,16 @@ public async Task SendMessage(string data)
_socket.Send(data);
}

/// <summary>
/// Triggered whenever an error occurs whenever we cannot raise an exception (because it could not be caught).
/// </summary>
private void Error(Exception e)
{
var handler = OnError;
if (handler != null) handler(this, new ExceptionEventArgs { Exception = e });
}

public event EventHandler<ExceptionEventArgs> OnError;
public event EventHandler<EventArgs> OnClose;
public event EventHandler<EventArgs> OnOpen;
public event EventHandler<DataReceivedEventArgs> OnData;
Expand Down
42 changes: 37 additions & 5 deletions Pusher.Connections.WindowsStore/WebSocketConnection.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Globalization.DateTimeFormatting;
using Pusher.Events;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
Expand Down Expand Up @@ -32,19 +33,30 @@ private async void OnMessageReceived(MessageWebSocket sender, MessageWebSocketMe
{
if (OnData == null) return;

var exceptionOccured = false;
Exception exception = null;
try
{
var reader = args.GetDataReader();
var text = reader.ReadString(reader.UnconsumedBufferLength);
OnData(sender, new DataReceivedEventArgs { TextData = text });
}
catch (Exception)
catch (Exception e)
{
exceptionOccured = true;
exception = e;
}
// cannot await in catch
if (exceptionOccured) await Reconnect();
if (exception != null)
{
_connectionState = ConnectionState.Failed;
try
{
await Reconnect();
}
catch (Exception e)
{
Error(e);
}
}
}

private async Task Reconnect()
Expand All @@ -60,7 +72,16 @@ private async void OnSocketClosed(IWebSocket sender, WebSocketClosedEventArgs ar
_messageWriter = null;
if (_connectionState != ConnectionState.Disconnecting)
{
await Reconnect();
_connectionState = ConnectionState.Failed;
try
{
await Reconnect();
}
catch (Exception e)
{
Error(e);
return;
}
}
_connectionState = ConnectionState.Disconnected;
if (OnClose != null) OnClose(sender, new EventArgs());
Expand Down Expand Up @@ -103,6 +124,17 @@ public async Task SendMessage(string data)
_messageWriter.WriteString(data);
await _messageWriter.StoreAsync();
}

public event EventHandler<ExceptionEventArgs> OnError;

/// <summary>
/// Triggered whenever an error occurs whenever we cannot raise an exception (because it could not be caught).
/// </summary>
private void Error(Exception e)
{
var handler = OnError;
if (handler != null) handler(this, new ExceptionEventArgs { Exception = e });
}

public event EventHandler<EventArgs> OnClose;
public event EventHandler<EventArgs> OnOpen;
Expand Down
10 changes: 7 additions & 3 deletions Pusher.Samples.WindowsStore/ViewModel/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,21 @@ private async void ConnectAsync()
{"channel", Channel}
});
}
_pusher = new Pusher(new WebSocketConnectionFactory(), AppKey, options);

var synchronizationContext = SynchronizationContext.Current;

_pusher = new Pusher(new WebSocketConnectionFactory(), AppKey, options);
_pusher.Logger = _logger;
_pusher.ExceptionOccured +=
(sender, args) => synchronizationContext.Post(
x => _logger.Debug("Exception occured: {0}", args.Exception.Message), null);

_logger.Debug("Connecting...");
await _pusher.ConnectAsync();
_logger.Debug("Connected!");
_logger.Debug("Subscribing to {0}!", Channel);
var channel = await _pusher.SubscribeToChannelAsync(Channel);

var synchronizationContext = SynchronizationContext.Current;

channel.GetEventSubscription<SubscriptionSucceededEventArgs>().EventEmitted += async (sender, evt) =>
{
synchronizationContext.Post(async channelName =>
Expand Down
6 changes: 4 additions & 2 deletions Pusher.Tests.WindowsStore/PusherTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,17 @@ public async Task SendMessage(string data)
}
}

public void SendData(string data)

public void SendData(string data)
{
if (OnData != null)
{
OnData(this, new DataReceivedEventArgs { TextData = data });
}
}

public event EventHandler<EventArgs> OnClose;
public event EventHandler<ExceptionEventArgs> OnError;
public event EventHandler<EventArgs> OnClose;
public event EventHandler<EventArgs> OnOpen;
public event EventHandler<DataReceivedEventArgs> OnData;
}
Expand Down
5 changes: 5 additions & 0 deletions Pusher/Events/DataReceivedEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ public class DataReceivedEventArgs : EventArgs
{
public string TextData { get; set; }
}

public class ExceptionEventArgs : EventArgs
{
public Exception Exception { get; set; }
}
}
10 changes: 10 additions & 0 deletions Pusher/IConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ public interface IConnection
void Close();
Task Open();
Task SendMessage(string data);
/// <summary>
/// Any exceptions thrown outside of calls to any of the methods
/// above, should not be thrown, but raise OnError.
///
/// This means that it is OK for Close(), Open() and SendMessage()
/// to throw exceptions. However, any internal reconnect logic
/// that fails should report it here. Also, if the connection is broken
/// this should be raised.
/// </summary>
event EventHandler<ExceptionEventArgs> OnError;
event EventHandler<EventArgs> OnClose;
event EventHandler<EventArgs> OnOpen;
event EventHandler<DataReceivedEventArgs> OnData;
Expand Down
26 changes: 25 additions & 1 deletion Pusher/Pusher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,35 @@ public async Task ConnectAsync()
_connection = _connectionFactory.Create(new Uri(string.Format("{0}://ws.pusherapp.com:{1}/app/{2}?protocol=5", _options.SchemeString, _options.Port,
ApplicationKey)));
_connection.OnData += ReceivedEvent;
_connection.OnError += OnError;
await _connection.Open();

await WaitForSingleEventAsync<ConnectionEstablishedEventArgs>();
}

public void AddContract(IEventContract contract)
private void OnError(object sender, ExceptionEventArgs e)
{
if (_connection is IDisposable)
{
(_connection as IDisposable).Dispose();
}
_connection = null;
if (ExceptionOccured == null) return;
ExceptionOccured(this, e);
}

/// <summary>
/// Events that cannot be otherwise caught (e.g. something happens to
/// a connection while you are not doing anything to it) are
/// reported through this event.
///
/// When you receive this event, the connection is permanently broken,
/// but you can call ConnectAsync() again (but remember to catch its
/// Exceptions).
/// </summary>
public EventHandler<ExceptionEventArgs> ExceptionOccured;

public void AddContract(IEventContract contract)
{
if (_contracts.Any(c => c.Name == contract.Name))
{
Expand Down Expand Up @@ -198,6 +221,7 @@ private static Channel CreateChannel(string channelName)
public void Disconnect()
{
_connection.OnData -= ReceivedEvent;
_connection.OnError -= OnError;
_connection.Close();
_connection = null;
}
Expand Down

0 comments on commit 3af05e6

Please sign in to comment.