【发布时间】: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。我不认为这是服务器端问题,但在排除该选项之前,我需要再次验证未检测到拔出网络电缆。