C# - 处理关闭/断开Web Socket连接(CloseAsync vs CloseOutputAsync)

3

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

您可以使用CloseAsync和CloseOutputAsync方法,对于客户端发起和服务器发起的请求都可以关闭AspNetWebSocket连接。这两种方法以相同的方式处理客户端发起的请求:在客户端发送消息给服务器以关闭连接后,服务器调用其中一种方法并向客户端发送确认,然后该方法返回。

对于服务器发起的请求,这两种方法的工作方式不同。CloseAsync方法发送一个消息给客户端以关闭连接,等待响应,然后返回。服务器不等待客户端发送的任何其他数据。相反,CloseOutputAsync方法发送一个消息给客户端以关闭连接,并在不等待响应的情况下返回。方法返回后,您可以调用ReceiveAsync方法并处理客户端发送的任何其他数据或确认。

在我的应用程序中,客户端基本上只是接收来自服务器的更新,但从未在打开连接之外向服务器发送任何内容。但是客户端还需要能够从其侧关闭连接。基本上,服务器的角色是等待打开连接,发送一堆东西,并处理客户端关闭连接(但永远不必决定是否关闭连接)。因此,无论何时我们谈论清除地关闭连接,客户端都需要向服务器发送一条消息,表示它想要关闭连接,对吗?因此,客户端将需要执行类似以下操作的操作:
var x = await closeAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None)

服务器如何知道客户端执行了closeAsync?我尝试使用以下方式从服务器向客户端发送数据:
await sendAsync(new ArraySegment<byte>(infoBytes), 1, false, cancelled);

我收到了一个错误:

在调用 WebSocket.CloseAsync 后,接收到的消息类型“Text”无效。WebSocket.CloseAsync 应该仅在不再期望来自远程端点的数据时使用。相反,请使用“WebSocket.CloseOutputAsync”以继续能够接收数据但关闭输出通道。

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


该错误是关于在您的代码发送时接收到了数据。这两者不相匹配,发生了什么? - usr
客户端出现错误,当服务器端使用sendAsync时。发生了什么?这是我问的问题哈哈。 - Pipeline
1个回答

5

在服务器端:

 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引用中也说明了这一点。 - McGuireV10

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