OL.
OL.

Reputation: 211

What is the most proper way to close a websocket

In my .NET Core console app I use collection of ClientWebSocket objects to receive some data. When something goes wrong and an exception occurs I'd like to close all websockets.

I tried to do this in such way:

foreach (var socket in _sockets)
{
    if (socket.State == WebSocketState.Open || socket.State == WebSocketState.Connecting)
    {
        socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait();
    }
}

But in case of socket.State == WebSocketState.Connecting there is an exception:

System.AggregateException: 'One or more errors occurred. (The WebSocket is in an invalid state ('Connecting') for this operation. Valid states are: 'Open, CloseReceived, CloseSent')'

I know that I can use socket.Abort() for WebSocketState.Connecting as well as for WebSocketState.Open.

The question is whether it will be the most proper way to close the connections - by using CloseAsync for WebSocketState.Open and Abort for WebSocketState.Connecting?

Upvotes: 3

Views: 5914

Answers (1)

kahveci
kahveci

Reputation: 1457

Simply, you cannot close something that is not opened. The methods SendAsync, ReceiveAsync, CloseAsync, CloseOutputAsync always check the state of socket before taking any other action. If the state is not "connected", they throw exception.

The following states are considered as "not connected":

  • WebSocketState.None
  • WebSocketState.Connecting
  • WebSocketState.Closed

We can add WebSocketState.Aborted to the list as well.

Taking into account this fact, if you are not waiting a close request or sending one, you can close your sockets as simple as follows:

foreach (var socket in _sockets)
{
    if (socket.State == WebSocketState.Open)
    {
        await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
    }
}

I don't have the visibility of the remaining parts of your code. Therefore, I assume you try to run the CloseAsync method synchronously. I recommend that you think twice before using Wait() in async code. You literally block the current thread and waiting for the Task to complete. Do you really need this? You should use async all the way down as much as possible. Otherwise, you may end up deadlock in async code easily.

Upvotes: 5

Related Questions