WebSocket异常(0x80004005):远程一方在未完成关闭握手的情况下关闭了WebSocket连接。

22
我有一个使用WebSocket进行通信的Xamarin应用。在客户端方面,我正在引用ClientWebSocket

代码:

using (var client = new ClientWebSocket() { Options = { KeepAliveInterval = new TimeSpan(0,0,3,0) }})
{
    try
    {
        await client.ConnectAsync(requestUri, cancellationToken);
        do
        {
            WebSocketReceiveResult result = null;
            var buffer = new byte[ReceiveChunkSize];
            var message = new ArraySegment<byte>(buffer);
            do
            {
                result = await client.ReceiveAsync(message, cancellationToken);
                var receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);
                data.Append(receivedMessage);
                if (result.MessageType != WebSocketMessageType.Text)
                    break;

            } while (!result.EndOfMessage);

            TranslateData(data);
        } while (client.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested);
应用程序不断抛出间歇性错误。
 System.Net.WebSockets.WebSocketException (0x80004005): The remote
 party closed the WebSocket connection without completing the close
 handshake.

服务器有一个测试网站,看起来它的功能符合预期。问题似乎在客户端上。 client.State 中的值为Open


1
客户端离线时未进行关闭握手。这种情况很常见。只需处理此类型的异常以防止对系统造成任何损害。 - aleha_84
1
问题可能出在服务器端,它没有正确关闭WebSocket连接。 - Sergey.quixoticaxis.Ivanov
有什么猜测关于服务器在关闭连接的过程中可能出了什么问题吗? - Arshad Badar Khan
@ArshadBadarKhan 代码可能写错了:服务器会简单地忽略关闭。例如,如果服务器是 Windows 上的 .Net,则代码在首先调用 await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); 之前关闭 http 上下文。 - Sergey.quixoticaxis.Ivanov
2
请参阅RFC,关闭握手部分。服务器很可能只是关闭连接。 - Sergey.quixoticaxis.Ivanov
1个回答

1

如果有人像我一样仍然找到这个问题...

我遇到了同样的问题,所以我添加了这个检查。

result = await client.ReceiveAsync(message, cancellationToken);

if (result.Count == 0) {
    break;
}

获取零字节也意味着服务器已结束连接或发生了错误...

我在 WebSocket 周围添加了一个计时器来进行 ping -> pong 类型的连接检查。当然,这仅在您同时控制服务器端代码时才可能。在服务器端,这将帮助您检测死亡连接。

帮助我的链接:

https://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html

https://social.msdn.microsoft.com/Forums/vstudio/en-US/77bda5ed-0d52-4305-9a20-438e69dc2cb0/c-advanced-socket-server-100-cpu-usage-after-some-time?forum=csharpgeneral

就像aleha_84所写的一样。您的循环中的异常还应触发重新连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接