Отключение дескриптора ClientWebSocket без чтения с него - PullRequest
0 голосов
/ 07 марта 2019

Короткая версия: Кто-нибудь знает безопасный и надежный механизм для обнаружения разъединения ClientWebSocket, инициированного сервером, без активного чтения из сокета и проверки WebSocketMessageType.Close.Я хочу асинхронно установить CancellationToken, когда сервер решает отключиться, пока я могу обработать некоторые данные после получения.

Длинная версия с вариантом использования:

В моем приложении у меня есть ClientWebSocket, который получает некоторые данные с сервера.Исходным сообщением, которое я получаю по соединению, я инициирую дальнейшую логику приложения, которая может считывать дополнительные данные из WebSocket или просто инициировать другие операции, такие как запрос к базе данных.Когда я запускаю логику приложения, я передаю CancellationToken, который я хочу использовать в случае, если на веб-сокете произойдет что-то непредвиденное.Таким образом, я хочу отменить любые операции в цепочке приложений, если они больше не нужны.

Теперь проблема в том, что кажется, что отключение WebSocket, похоже, правильно обнаруживается только при взаимодействии с WebSocket, как при чтении с него и проверке WebSocketMessageType.Close.Но чтение из WebSocket для потенциального события закрытия может привести к чтению некоторых фактических данных, которые должны выполняться отдельно логикой приложения.

Представьте себе следующий счастливый процесс:

  1. Я подключаюсь к серверу через ClientWebSocket.
  2. Я получаю исходное сообщение WebSocketMessageType.Text, которое вызывает некоторую логику приложения.
  3. Сервер начинает потоковую передачу некоторых данных с помощью сообщений WebSocketMessageType.Binary.
  4. В клиентском приложении я запускаю обработку этих данных, которая может привести к асинхронным операциям с передаваемым везде CancellationToken.
  5. Данные обрабатываются, и я отправляю сообщение WebSocketMessageType.Text на сервер и закрываю соединение.

В любой момент сервер может решить прервать эту связь.Он отправит сообщение о закрытии, а затем закроет соединение.Это также может быть просто разрыв сети, обнаруженный механизмом KeepAlive или операционной системой.На стороне клиента я хочу иметь асинхронное событие, уведомляющее меня об этом закрытии, которое позволяет мне установить CancellationToken.

Я думал о различных решениях, но на самом деле ничего не подходит:

  1. Я думал об отдельном опросе с чтением 0 байтов для проверки события закрытия, которое имеет 2 неопределенности.WebSocket не поддерживает одновременное чтение нескольких потоков из разных потоков.Моя логика приложения не сможет больше читать из потока.Я не уверен, что WebSocket проигнорирует мой 0-байтовый приемный буфер и потенциально прочитает некоторые данные, повреждая кадрирование данных приложения.

  2. У меня активна система KeepAlive на моей веб-розетке.Вместо чтения из сокета я мог только опросить текущие WebSocket State и CloseStatus.Но также я сомневаюсь, что состояния обновляются, если я не читаю из них.

Я немного запутался в этой теме.Реализация WebSocket в C # действительно находится на низком уровне и многое оставляет разработчикам с развязкой.В JavaScript я просто подключаюсь к событию message для получения данных и событию close для отправки сигнала остановки WebWorker.Со смешением событий данных и события закрытия в одном приеме я не вижу, как я могу разделить их в своем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...