c# - Websocket 的 ReceiveAsync 方法不等待整个消息

标签 c# websocket async-await

我正在通过 websocket 接收 JSON。至少:我是部分的。使用在线 websocket 服务,我收到完整的 JSON 响应(所有 HTML 标记都被忽略)。当我查看在控制台中收到的 JSON 时,我可以看到 HTML 标记(在调试期间使用 HTML 查看器查看它会删除 HTML)但它突然结束(数据不完整)。

我的缓冲区有足够的空间,我正在使用 async-await 来(据说)等待整个响应进入,然后再继续。

private async Task Receive()
{
  var buffer = new byte[4096 * 20];

  while (_socket.State == WebSocketState.Open)
  {
      var response = await _socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

      if (response.MessageType == WebSocketMessageType.Close)
      {
          await
              _socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close response received",
                  CancellationToken.None);
      }
      else
      {
          var result = Encoding.UTF8.GetString(buffer);
          var a = buffer[1000];
          var b = buffer[10000];
          var c = buffer[50000];
          var d = buffer[81000];
          Console.WriteLine(result);
          var responseObject = JsonConvert.DeserializeObject<Response>(result, _requestParameters.ResponseDataType);

          OnSocketReceive.Invoke(this, new SocketEventArgs {Response = responseObject });
          buffer = new byte[4096 * 20];
      }
  }
}   

注意事项:缓冲区足够大,bcd 永远不会被填满。我还应该注意,这只发生在 1-questions-newest-tag-java 请求中,155-questions-active 工作得很好。

在做了一些挖掘之后,我发现 response.CloseStatusresponse.CloseStatusDescription 总是 nullresponse.Count 始终为 1396(在 Word 中复制粘贴结果确实显示始终有 1396 个字符)并且 response.EndOfMessagefalse .

挖掘some source code我发现 DefaultReceiveBufferSize16 * 1024(足够大)并且 WebSocketGetDefaultKeepAliveInterval() 指的是 an external implementation (但调试器显示 00:00:30)。

这不是超时问题,因为调试器会在在线服务收到响应的同时停止。

为什么我的方法在套接字还没有收到所有数据时继续执行?

最佳答案

只是为了完成@Noseratio 的响应,代码应该是这样的:

ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[8192]);

WebSocketReceiveResult result= null;

using (var ms = new MemoryStream())
{
     do
     {
         result = await socket.ReceiveAsync(buffer, CancellationToken.None);
         ms.Write(buffer.Array, buffer.Offset, result.Count);
     }
     while (!result.EndOfMessage);

     ms.Seek(0, SeekOrigin.Begin);

     if (result.MessageType == WebSocketMessageType.Text)
     {
          using (var reader = new StreamReader(ms, Encoding.UTF8))
          {
               // do stuff
          }
     }
}

干杯。

关于c# - Websocket 的 ReceiveAsync 方法不等待整个消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23773407/

相关文章:

c# - 多少异步/等待是可以的?

c# - 如何从另一台服务器上的用户界面(网页)调用一台服务器上的 API?

c# - 调用线程无法访问此对象,因为另一个线程拥有它

c# - IMemoryCache 保证唯一的新 key .NET-Core

java - Websocket 在 playframework 2 中向所有客户端发送数据

node.js - 与 api 一起使用的 Node js websockets

javascript - JavaScript WebSockets API 的机制

.net - 什么 "Current"属性与 ExecutionContext 一起流动

c# - 如何访问嵌入式附件?

c# - 如何确保多个异步下载的数据按照开始的顺序保存?