 
I recently talked about .NET WebSocket Libraries, and how I like using WebSocket4Net as a .NET WebSocket client. That library is great, but really wanted it to have two additional features:
- Retry logic for opening a connection.
- An OpenAsync method.
...so I created an extension method that does both!
WebSocket4Net Extensions
public static class WebSocketExtensions
{
public static async Task OpenAsync(
        this WebSocket webSocket,
        int retryCount = 5,
        CancellationToken cancelToken = default(CancellationToken))
    {
        var failCount = 0;
var exceptions = new List<Exception>(retryCount);
var openCompletionSource = new TaskCompletionSource<bool>();
cancelToken.Register(() => openCompletionSource.TrySetCanceled());
        EventHandler openHandler = (s, e) => openCompletionSource.TrySetResult(true);
EventHandler<ErrorEventArgs> errorHandler = (s, e) =>
        {
            if (exceptions.All(ex => ex.Message != e.Exception.Message))
            {
exceptions.Add(e.Exception);
}
};
EventHandler closeHandler = (s, e) =>
        {
            if (cancelToken.IsCancellationRequested)
            {
openCompletionSource.TrySetCanceled();
}
else if (++failCount < retryCount)
            {
webSocket.Open();
}
            else
            {
                var exception = exceptions.Count == 1
? exceptions.Single()
                    : new AggregateException(exceptions);
var webSocketException = new WebSocketException(
                    "Unable to connect", 
exception);
openCompletionSource.TrySetException(webSocketException);
}
};
        try
        {
webSocket.Opened += openHandler;
webSocket.Error += errorHandler;
webSocket.Closed += closeHandler;
webSocket.Open();
            await openCompletionSource.Task.ConfigureAwait(false);
}
        finally
        {
webSocket.Opened -= openHandler;
webSocket.Error -= errorHandler;
webSocket.Closed -= closeHandler;
}
}
Enjoy,
Tom
 
 
No comments:
Post a Comment