Короткая версия: Кто-нибудь знает безопасный и надежный механизм для обнаружения разъединения ClientWebSocket
, инициированного сервером, без активного чтения из сокета и проверки WebSocketMessageType.Close
.Я хочу асинхронно установить CancellationToken
, когда сервер решает отключиться, пока я могу обработать некоторые данные после получения.
Длинная версия с вариантом использования:
В моем приложении у меня есть ClientWebSocket
, который получает некоторые данные с сервера.Исходным сообщением, которое я получаю по соединению, я инициирую дальнейшую логику приложения, которая может считывать дополнительные данные из WebSocket или просто инициировать другие операции, такие как запрос к базе данных.Когда я запускаю логику приложения, я передаю CancellationToken
, который я хочу использовать в случае, если на веб-сокете произойдет что-то непредвиденное.Таким образом, я хочу отменить любые операции в цепочке приложений, если они больше не нужны.
Теперь проблема в том, что кажется, что отключение WebSocket, похоже, правильно обнаруживается только при взаимодействии с WebSocket, как при чтении с него и проверке WebSocketMessageType.Close
.Но чтение из WebSocket для потенциального события закрытия может привести к чтению некоторых фактических данных, которые должны выполняться отдельно логикой приложения.
Представьте себе следующий счастливый процесс:
- Я подключаюсь к серверу через ClientWebSocket.
- Я получаю исходное сообщение
WebSocketMessageType.Text
, которое вызывает некоторую логику приложения. - Сервер начинает потоковую передачу некоторых данных с помощью сообщений
WebSocketMessageType.Binary
. - В клиентском приложении я запускаю обработку этих данных, которая может привести к асинхронным операциям с передаваемым везде CancellationToken.
- Данные обрабатываются, и я отправляю сообщение
WebSocketMessageType.Text
на сервер и закрываю соединение.
В любой момент сервер может решить прервать эту связь.Он отправит сообщение о закрытии, а затем закроет соединение.Это также может быть просто разрыв сети, обнаруженный механизмом KeepAlive или операционной системой.На стороне клиента я хочу иметь асинхронное событие, уведомляющее меня об этом закрытии, которое позволяет мне установить CancellationToken.
Я думал о различных решениях, но на самом деле ничего не подходит:
Я думал об отдельном опросе с чтением 0 байтов для проверки события закрытия, которое имеет 2 неопределенности.WebSocket не поддерживает одновременное чтение нескольких потоков из разных потоков.Моя логика приложения не сможет больше читать из потока.Я не уверен, что WebSocket проигнорирует мой 0-байтовый приемный буфер и потенциально прочитает некоторые данные, повреждая кадрирование данных приложения.
У меня активна система KeepAlive на моей веб-розетке.Вместо чтения из сокета я мог только опросить текущие WebSocket State
и CloseStatus
.Но также я сомневаюсь, что состояния обновляются, если я не читаю из них.
Я немного запутался в этой теме.Реализация WebSocket в C # действительно находится на низком уровне и многое оставляет разработчикам с развязкой.В JavaScript я просто подключаюсь к событию message
для получения данных и событию close
для отправки сигнала остановки WebWorker.Со смешением событий данных и события закрытия в одном приеме я не вижу, как я могу разделить их в своем коде.