【问题标题】:ClientWebSocket make sure that message has been sent and connection is aliveClientWebSocket 确保消息已发送且连接处于活动状态
【发布时间】:2017-12-24 15:03:28
【问题描述】:

背景:外部因素迫使我在 C# 中实现一个简单的 websocket 客户端,我希望保持第三方依赖的数量较少。因此,如果可能的话,最好坚持使用 System.Net.WebSockets。

目标:将一系列 JSON 对象作为单独的消息发送到 websocket 服务器。如果发送失败并出现任何合理的超时,则抛出异常。如果新对象可用时底层 TCP 连接中断,则引发异常。

发送代码:

// ws is an instance of System.Net.WebSockets.ClientWebSocket
ArraySegment<byte> json = new ArraySegment<byte> 
Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data)));

if (!ws.SendAsync(json, WebSocketMessageType.Binary, true, 
CancellationToken.None).Wait(10000))
{
    throw new Exception("Error: Websocket send timeout");
}
Console.Write("Sent")

我对这段代码的问题是,当我看到客户端程序打印“Sent”时,服务器将在多次调用 SendAsync 之前接收到该消息。我的印象是它被困在某种内部消息缓冲区中,直到缓冲区溢出。

同样,中断底层 TCP 连接不会导致下一个 SendAsync 抛出异常,直到之后的几条消息。

在不发送的情况下检查 websocket 是否存活: keepalive 设置为默认值 30s。然而,我从未见过 ws.State 除了 WebSocketState.Open 之外返回任何内容,即使在断开服务器连接几分钟后,如果我之间没有任何消息要发送。

我是否从根本上对应该如何使用 ClientWebSocket 感到困惑,它根本不起作用,还是我错过了文档中的一些细节?

【问题讨论】:

  • 您应该使用原始套接字还是网络套接字?如果您使用的是 websockets,那么 .NET websocket 会处理超时、失败和断开的连接。听起来这可能是服务器端的问题。
  • 我也在服务器上使用 websockets。我不认为这是服务器端问题,但在排除该选项之前,我需要再次验证未检测到拔出网络电缆。

标签: c# .net


【解决方案1】:

您应该在 Task.Runawait 使用您的异步方法:

Task.Run(() => {  
  if (!await ws.SendAsync(json, WebSocketMessageType.Binary, true, 
  CancellationToken.None))
  {
    throw new Exception("Error: Websocket send timeout");
  }
  Console.Write("Sent");
} ).Wait(10000);

【讨论】:

  • 谢谢。你能澄清一下为什么 await 和 Task.Run 是必要的吗?我的印象是 .Wait(10000) 应该阻塞直到发送完成或超时? await 在这里完成了什么?关于Task.Run():那不会让这段代码再次非阻塞吗?也许我没有在我的问题中明确表示我希望代码在消息发送或发送失败之前被阻止。
  • 对不起,我忘了移动等待,现在只有完成后你才会写“已发送”,这就是这样做的全部目的。
  • 谢谢,看起来应该可以了。但我仍然对 await 和 .Wait() 之间的区别感到困惑。我认为 await 和 .Wait(-1) 会使语句阻塞具有相同的效果。我最初的尝试有什么问题。
  • 它不会解决你的问题,但你可以根据console.write("sent")附近的部分是否执行来解决问题。
  • 我不明白你最后的评论。我会尽快尝试您的代码,但目前我不明白为什么 await 应该完成 .Wait() 未能完成的事情(阻止直到消息实际发送)。在接受答案之前,我必须了解这一点。如果我正确理解您的想法,我还认为应该将ifConsole.Write("Sent") 移到Task.Run 块之外,否则在超时的情况下不会发生异常。
猜你喜欢
  • 2012-11-04
  • 2021-12-24
  • 2010-11-19
  • 2012-01-03
  • 2021-09-13
  • 2013-08-27
  • 2019-09-01
  • 1970-01-01
  • 2018-03-16
相关资源
最近更新 更多