Как правильно закрыть веб-розетку? - PullRequest
0 голосов
/ 06 сентября 2018

В своем консольном приложении .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?

1 Ответ

0 голосов
/ 19 июля 2019

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

...