Как правильно закрыть веб-розетку?

В моем консольном приложении.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полностью вниз, насколько это возможно. В противном случае вы можете легко попасть в тупик в асинхронном коде.

Другие вопросы по тегам