#c# #.net #websocket #real-time #clientwebsocket
Вопрос:
Я хотел бы создать клиент websocket для подключения к стороннему серверу веб-сокетов.
Я использую класс ClientWebSocket:
public WSClientService(ClientWebSocket client, ILogger<WSClientService> logger)
{
_client = client;
_logger = logger;
}
Для получения сообщений я использую этот метод:
public async Task GetMessagesAsync()
{
while (_client.State == WebSocketState.Open)
{
var chunkSize = 1024 * 4;
var buffer = new ArraySegment<byte>(new byte[chunkSize]);
do
{
WebSocketReceiveResult resu<
using var ms = new MemoryStream();
try
{
do
{
//here throws exception
result = await _client.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.Array, buffer.Offset, result.Count);
} while (!result.EndOfMessage);
if (result.MessageType == WebSocketMessageType.Close)
{
break;
}
ms.Seek(0, SeekOrigin.Begin);
using var reader = new StreamReader(ms, Encoding.UTF8);
var message = await reader.ReadToEndAsync();
_logger.LogInformation(message);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
} while (_client.State != WebSocketState.Aborted);
}
}
Но для некоторых сообщений я получаю это сообщение об исключении :
The WebSocket received a frame with one or more reserved bits set
Я заметил, что это происходит, вероятно, из-за некоторого сжатия, потому что я могу получать небольшие сообщения. Исключение, возникающее при вызове этого result = await _client.ReceiveAsync(buffer, CancellationToken.None);
Кто-нибудь знает, как решить эту проблему?
Ответ №1:
Решение пришло с выпуском .net 6. Ну, проблема возникла из-за того, что не было возможности добавить сжатие во встроенный ClientWebSocket в .net 5 и обратно (за исключением случаев, когда кто-то создавал метод расширения для сжатия). Теперь в .net 6 появилась новая опция с именем DangerousDeflateOptions
. Это также добавляет соответствующий заголовок.
_ws.Options.DangerousDeflateOptions = new WebSocketDeflateOptions
{
ServerContextTakeover = false,
ClientMaxWindowBits = 15 // this is the default value
};
await _ws.ConnectAsync(new Uri(_url), token).ConfigureAwait(false);