简体   繁体   English

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

[英]c# - Handling closing/disconnecting web socket connections (CloseAsync vs CloseOutputAsync)

I am trying to understand and handle the different ways a web socket connection could be closed.我试图了解和处理关闭网络套接字连接的不同方式。 From msdn :msdn

You can use the CloseAsync and CloseOutputAsync methods for both client-initiated and server-initiated requests to close an AspNetWebSocket connection.您可以对客户端发起和服务器发起的请求使用 CloseAsync 和 CloseOutputAsync 方法来关闭 AspNetWebSocket 连接。 The two methods handle client-initiated requests in the same way: After the client sends a message to the server to close the connection, the server calls one of these methods and sends an acknowledgment to the client, and then the method returns.这两种方法以相同的方式处理客户端发起的请求:客户端向服务器发送关闭连接的消息后,服务器调用其中一个方法并向客户端发送确认,然后该方法返回。

For server-initiated requests, the two methods work differently.对于服务器发起的请求,这两种方法的工作方式不同。 The CloseAsync method sends a message to the client to close the connection, waits for a response, and then returns. CloseAsync 方法向客户端发送消息以关闭连接,等待响应,然后返回。 The server does not wait for any additional data sent by the client.服务器不会等待客户端发送的任何其他数据。 In contrast, the CloseOutputAsync method sends a message to the client to close the connection and returns without waiting for a response.相比之下,CloseOutputAsync 方法向客户端发送消息以关闭连接并返回,而无需等待响应。 After the method returns, you can call the ReceiveAsync method and handle either additional data or the acknowledgment that the client sends.该方法返回后,您可以调用 ReceiveAsync 方法并处理附加数据或客户端发送的确认。

In my application the client basically sits there receiving updates from the server, but never actually sends anything to the server outside of opening the connection.在我的应用程序中,客户端基本上坐在那里从服务器接收更新,但在打开连接之外实际上从未向服务器发送任何内容。 However the client also needs to be able to close the connection from their side.然而,客户端也需要能够从他们这边关闭连接。

Basically the server's role is to sit there waiting to open a connection, send a bunch of stuff, and handle clients closing connections (but never has to decide to close the connection or not).基本上服务器的角色是坐在那里等待打开连接,发送一堆东西,并处理客户端关闭连接(但永远不必决定是否关闭连接)。

So no matter, when we are talking about cleanly closing a connection, a client needs to send the server a message saying it wants to close the connection, correct?所以无论如何,当我们谈论干净地关闭连接时,客户端需要向服务器发送一条消息,说它想关闭连接,对吗?

So the client will need to do something like:因此,客户端将需要执行以下操作:

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

How does the server know the client executed closeAync?服务器如何知道客户端执行了 closeAync? I tried to send a piece of data from server to client using:我尝试使用以下方法将一段数据从服务器发送到客户端:

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

and received an error:并收到一个错误:

"The received message type 'Text' is invalid after calling WebSocket.CloseAsync. WebSocket.CloseAsync should only be used if no more data is expected from the remote endpoint. Use 'WebSocket.CloseOutputAsync' instead to keep being able to receive data but close the output channel." “在调用 WebSocket.CloseAsync 后,接收到的消息类型 'Text' 无效。仅当远程端点没有更多数据时才应使用 WebSocket.CloseAsync。改用 'WebSocket.CloseOutputAsync' 以保持能够接收数据但关闭输出通道。”

So how on the server side do I know if the client is trying to cleanly close the connection?那么在服务器端我如何知道客户端是否正在尝试干净地关闭连接?

On the server side :在服务器端:

 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;
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM