一个的WebSocket的ReceiveAsync方法不会等待整个消息 [英] A websocket's ReceiveAsync method does not await the entire message

查看:3980
本文介绍了一个的WebSocket的ReceiveAsync方法不会等待整个消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am receiving JSON through a websocket. At least: I am partially. Using an online websocket service I receive the full JSON response (all the HTML markup is ignored). When I look at the JSON that I receive in my console I can see the HTML markup (viewing it with the HTML viewer during debugging removes the HTML) but it ends abruptly (incomplete data).

我的缓冲区中有足够的空间,我用异步等待来(据说)等待整个响应,然后再继续进去。

My buffer has plenty of space and I am using async-await to (supposedly) wait for the entire response to come in before continuing.

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];
      }
  }
}   

注意事项:缓冲区是不够完美的大和 B C ð永远不会填满。我也应该注意到,这只是发生在 1疑问的最新标签-java的要求, 155-问题主动运行完美。

Things to note: The buffer is perfectly big enough and b, c and d are never filled. I should also note that this only happens for the 1-questions-newest-tag-java request, 155-questions-active works perfectly fine.

做一些挖掘,我发现之后, response.CloseStatus response.CloseStatusDescription 总是无效 response.Count 总是 1396 (复制粘贴结果Word会显示总有1396个字符)和 response.EndOfMessage

After doing some digging I have found that response.CloseStatus and response.CloseStatusDescription are always null, response.Count is always 1396 (copy-pasting the result in Word does show that there are always 1396 characters) and response.EndOfMessage is false.

到<挖掘href=\"http://referencesource.microsoft.com/#System/net/System/Net/WebSockets/ClientWebSocket.cs#6fd04c76fe32d754\"相对=nofollow>部分源$ C ​​$ C 我发现,<一个href=\"http://referencesource.microsoft.com/#System/net/System/Net/WebSockets/WebSocketHelpers.cs#285b8b64a4da6851\"相对=nofollow> DefaultReceiveBufferSize 16×1024 (足够大)和 WebSocketGetDefaultKeepAliveInterval()指<一个href=\"http://referencesource.microsoft.com/#System/net/System/Net/WebSockets/WebSocketProtocolComponent.cs#3039008acf8baff7\"相对=nofollow>外部实现(但调试器显示 00:00:30 )。

Digging through some source code I have found that the DefaultReceiveBufferSize is 16 * 1024 (big enough) and the WebSocketGetDefaultKeepAliveInterval() refers to an external implementation (but the debugger shows 00:00:30).

这不是超时的问题,因为在调试器暂停在在线服务接收其响应的同一时刻。

It is not a matter of timeout since the debugger halts at the same moment the online service receives its response.

为什么我的方法继续当套接字尚未收到的所有数据执行?

Why is my method continuing to execute when the socket has not yet received all data?

推荐答案

我可能是错的,但我不认为你总是应该得到一个完整的的WebSocket 消息一次。服务器可以在块区发送消息(那简直相当于调用 SendAsync endOfMessage:假

I might be wrong, but I don't think you're always supposed to receive a complete WebSocket message at once. The server may be sending the message in chunks (that'd correspond to calling SendAsync with endOfMessage: false).

那么,做等待_socket.ReceiveAsync()在一个循环和积累所接收到的数据块,直到 WebSocketReceiveResult.EndOfMessage 真正或错误发生。

So, do await _socket.ReceiveAsync() in a loop and accumulate the received chunks, until WebSocketReceiveResult.EndOfMessage is true or an error has occured.

在一个侧面说明,你应该使用 WebSocket.CreateClientBuffer 而不是新ArraySegment&LT;字节&GT;(缓冲)

On a side note, you probably should be using WebSocket.CreateClientBuffer instead of new ArraySegment<byte>(buffer).

这篇关于一个的WebSocket的ReceiveAsync方法不会等待整个消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆