关闭WebSocket的最合适方法是什么

时间:2018-09-06 14:35:36

标签: c# .net-core clientwebsocket

在我的.NET Core控制台应用程序中,我使用ClientWebSocket对象的集合来接收一些数据。当出现问题并发生异常时,我想关闭所有websocket。

我试图以这种方式做到这一点:

foreach (var socket in _sockets)
{
    if (socket.State == WebSocketState.Open || socket.State == WebSocketState.Connecting)
    {
        socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait();
    }
}

但是对于socket.State == WebSocketState.Connecting,有一个例外:

  

System.AggregateException:'发生一个或多个错误。 (此操作的WebSocket处于无效状态(“正在连接”)。有效状态为:“打开,CloseReceived,CloseSent”)”

我知道我可以为socket.Abort()WebSocketState.Connecting使用WebSocketState.Open

问题是,关闭连接是否是最合适的方法-通过对CloseAsync使用WebSocketState.Open和对Abort使用WebSocketState.Connecting

1 个答案:

答案 0 :(得分:0)

简而言之,您无法关闭未打开的东西。方法SendAsyncReceiveAsyncCloseAsyncCloseOutputAsync始终在执行任何其他操作之前检查套接字的状态。如果状态不是“已连接”,则抛出异常。

以下状态被视为“未连接”:

  • WebSocketState.None
  • WebSocketState.Connecting
  • WebSocketState.Closed

我们也可以将WebSocketState.Aborted添加到列表中。

考虑到这一事实,如果您不等待关闭请求或发送请求,则可以像下面这样简单地关闭套接字:

foreach (var socket in _sockets)
{
    if (socket.State == WebSocketState.Open)
    {
        await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
    }
}

我看不到代码其余部分的可视性。因此,我假设您尝试同步运行CloseAsync方法。我建议您在异步代码中使用Wait()之前要三思。您实际上阻止了当前线程,并等待Task完成。你真的需要这个吗?您应尽可能完全使用async。否则,您可能很容易在异步代码中陷入僵局。