Reputation: 211
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
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