У меня есть приложение, в котором я использую класс System.Net.Websockets.WebSocket
для отправки информации через веб-сокет. Все работает хорошо, за исключением неприятных деталей. Когда происходит ошибка, я хочу, чтобы сервер отправил сообщение об ошибке через веб-сокет, а затем закрыл соединение. Это работает так:
private async Task CloseOnError(ErrorMessage error, WebSocket socket)
{
await SendErrorMessage(error, socket);
await socket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "ClosedOnError", CancellationToken.None);
return;
}
private async Task SendErrorMessage(ErrorMessage error, WebSocket socket)
{
await SendMessageAsync(socket, JsonConvert.SerializeObject(error));
return;
}
private async Task SendMessageAsync(WebSocket socket, string message)
{
if (socket == null || socket.State != WebSocketState.Open)
{
return;
}
await socket.SendAsync(
buffer: new ArraySegment<byte>(
array: Encoding.ASCII.GetBytes(message),
offset: 0,
count: message.Length),
messageType: WebSocketMessageType.Text,
endOfMessage: true,
cancellationToken: CancellationToken.None);
}
Я вызываю CloseOnError
, передавая пользовательский объект ErrorMessage
и экземпляр WebSocket
, который я использую. SendErrorMessage
отправляет ошибку, сериализованную в json, через веб-сокет, а затем я закрываю веб-сокет, используя socket.CloseAsync
.
При запуске программы клиент websocket никогда не получает сообщение об ошибке. Однако, если я отлаживаю программу и запускаю ее шаг за шагом, клиент получает сообщение об ошибке. Похоже, что после отправки происходит так быстро, что данные не сбрасываются в основной сокет. Фактически, если поставить Thread.sleep(1000)
после await SendErrorMessage
, клиент получит данные.
Я искал способы очистки буфера сокета перед закрытием, но я не нашел ни одного ( класс WebSocket , по-видимому, не разрешает доступ к базовому сокету).
Как сделать так, чтобы сообщение об ошибке появилось на проводе, не используя этот неприятный Thread.sleep()
?