.NET WebSocket:CloseOutputAsync与CloseAsync的区别

18
我们有一个ASP.NET Web API REST服务正在工作中,其中一个控制器方法使用HttpContext.AcceptWebSocketResponse(..)来使用WebSockets。

代码中的socket handler看起来类似于这样...

public async Task SocketHandler(AspNetWebSocketContext context)
{
    _webSocket = context.WebSocket;
    ...
    while(!cts.IsCancellationRequested)
    {
        WebSocketReceiveResult result = _webSocket.ReceiveAsync(inputSegment, cts.Token).Result;
        WebSocketState currentSocketState = _webSocket.State;

        if (result.MessageType == WebSocketMessageType.Close ||
            currentSocketState == WebSocketState.CloseReceived)
        {
            // Should I use .CloseAysnc() or .CloseOutputAsync()?
            _webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "client requested", cts.Token).Wait();
        }

        if (currentSocketState == WebSocketState.Open)
        {
        ...
        }
    }
}

.CloseAsync()和CloseOutputAysnc()有什么区别?我尝试了两种方法,它们似乎都可以正常工作,但一定有一些区别。在MSDN上它们的描述非常相似...

System.Net.WebSockets.CloseAsync -- 使用WebSocket协议规范第7节定义的关闭握手,以异步操作的方式关闭WebSocket连接。

System.Net.WebSockets.CloseOutputAsync -- 启动或完成WebSocket协议规范第7节中定义的关闭握手。

1个回答

18

https://www.salmanq.com/blog/5-things-you-probably-didnt-know-about-net-websockets/

...优雅的方式是CloseAsync,在初始化时向连接方发送消息,并等待确认。...另一个选择是使用CloseOutputAsync,这更像是一种“点火并忘记”的方法。...

看起来你正在接收关闭消息;

if (result.MessageType == WebSocketMessageType.Close ||
            currentSocketState == WebSocketState.CloseReceived)

所以我会说,你完全可以使用CloseOutputAsync,因为你已经收到了一条消息,表明“我想关闭这个连接”。


1
加一。尽管<sarcasm>我喜欢参考文章和https://mcguirev10.com/2019/08/17/how-to-close-websocket-correctly.html的作者花时间更新官方微软文档而不是写自己的博客文章</sarcasm>。 - Ash

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