Как правильно закрыть веб-розетку?
В моем консольном приложении.NET Core я использую коллекцию объектов ClientWebSocket для получения некоторых данных. Когда что-то идет не так и возникает исключение, я бы хотел закрыть все веб-сокеты.
Я пытался сделать это таким образом:
foreach (var socket in _sockets)
{
if (socket.State == WebSocketState.Open || socket.State == WebSocketState.Connecting)
{
socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait();
}
}
Но в случае socket.State == WebSocketState.Connecting
есть исключение:
System.AggregateException: 'Произошла одна или несколько ошибок. (WebSocket находится в недопустимом состоянии ("Соединение") для этой операции. Допустимые состояния: "Open, CloseReceived, CloseSent")
Я знаю, что я могу использовать socket.Abort()
за WebSocketState.Connecting
а также для WebSocketState.Open
,
Вопрос в том, будет ли это наиболее правильным способом закрыть соединения - используя CloseAsync
за WebSocketState.Open
а также Abort
за WebSocketState.Connecting
?
0 ответов
Просто нельзя закрыть то, что не открывается. МетодыSendAsync
, ReceiveAsync
, CloseAsync
, CloseOutputAsync
всегда проверяйте состояние сокета, прежде чем предпринимать какие-либо другие действия. Если состояние не "подключено", они генерируют исключение.
Следующие состояния считаются "не подключенными":
WebSocketState.None
WebSocketState.Connecting
WebSocketState.Closed
Мы можем добавить WebSocketState.Aborted
к списку.
Принимая во внимание этот факт, если вы не ждете запроса на закрытие или не отправляете его, вы можете закрыть свои сокеты следующим образом:
foreach (var socket in _sockets)
{
if (socket.State == WebSocketState.Open)
{
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
}
}
Мне не видны остальные части вашего кода. Поэтому я предполагаю, что вы пытаетесь запуститьCloseAsync
метод синхронно. Я рекомендую вам дважды подумать перед использованиемWait()
в асинхронном коде. Вы буквально блокируете текущий поток и ждетеTask
завершить. Вам это действительно нужно? Вы должны использоватьasync
полностью вниз, насколько это возможно. В противном случае вы можете легко попасть в тупик в асинхронном коде.