c# - 处理关闭/断开 Web 套接字连接(CloseAsync 与 CloseOutputAsync)

Posted

技术标签:

【中文标题】c# - 处理关闭/断开 Web 套接字连接(CloseAsync 与 CloseOutputAsync)【英文标题】:c# - Handling closing/disconnecting web socket connections (CloseAsync vs CloseOutputAsync) 【发布时间】:2015-07-06 19:45:49 【问题描述】:

我正在尝试了解和处理关闭 Web 套接字连接的不同方式。来自msdn:

您可以同时使用 CloseAsync 和 CloseOutputAsync 方法 客户端发起和服务器发起的关闭一个 AspNetWebSocket 连接。这两种方法处理客户端发起的 请求方式相同:客户端发送消息到 服务器关闭连接,服务器调用这些方法之一 并向客户端发送确认,然后是方法 返回。

对于服务器发起的请求,这两种方法都有效 不同。 CloseAsync 方法向客户端发送一条消息以 关闭连接,等待响应,然后返回。这 服务器不等待客户端发送的任何附加数据。在 相比之下,CloseOutputAsync 方法向客户端发送一条消息以 关闭连接并返回而不等待响应。后 方法返回,可以调用ReceiveAsync方法并处理 附加数据或客户端发送的确认。

在我的应用程序中,客户端基本上坐在那里从服务器接收更新,但实际上在打开连接之外从未向服务器发送任何内容。但是,客户端还需要能够从他们这边关闭连接。

基本上,服务器的角色是坐在那里等待打开连接,发送一堆东西,并处理客户端关闭连接(但永远不必决定是否关闭连接)。

所以不管怎样,当我们谈论干净地关闭连接时,客户端需要向服务器发送一条消息说它想要关闭连接,对吗?

所以客户需要做类似的事情:

var x = await closeAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None)

服务器如何知道客户端执行了closeAync?我尝试使用以下方式将一条数据从服务器发送到客户端:

await sendAsync(new ArraySegment<byte>(infoBytes), 1, false, cancelled);

并收到错误:

"调用后收到的消息类型'Text'无效 WebSocket.CloseAsync。 WebSocket.CloseAsync 只有在没有的情况下才应该使用 预计来自远程端点的更多数据。采用 'WebSocket.CloseOutputAsync' 改为继续接收 数据但关闭输出通道。”

那么在服务器端我如何知道客户端是否试图干净地关闭连接?

【问题讨论】:

该错误涉及在您的代码发送时接收。两者不相配。怎么回事? 当服务器端使用 sendAsync 时,该错误出现在客户端。这是怎么回事?是我问的问题哈哈 【参考方案1】:

在服务器端:

 var result = await webSocket.ReceiveAsync(buffer, cancellationToken);

            if (result.MessageType == WebSocketMessageType.Close)
            
                await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Closed in server by the client", CancellationToken.None);
                return null;
            

【讨论】:

已编辑:CloseOutputAsync 是确认关闭帧的正确方法,而不是 CloseAsync。它甚至在 OP 的 MSDN 引用中这么说。

以上是关于c# - 处理关闭/断开 Web 套接字连接(CloseAsync 与 CloseOutputAsync)的主要内容,如果未能解决你的问题,请参考以下文章

JAVA:处理套接字断开连接

Winsock - 客户端断开连接,关闭套接字循环/最大连接数

客户端断开连接后,我是不是必须关闭服务器端的套接字?

C#检查套接字是不是断开连接?

不断开连接HttpUrlConnection意味着资源缺乏或网络滞后

Web Socket:无法在 Internet 断开连接时检测到客户端连接