【问题标题】:How to handle the close handshake c#如何处理关闭握手c#
【发布时间】:2020-10-29 20:24:33
【问题描述】:

我使用 websockets 和 https 调用在 c# 中开发了一个猜谜游戏。每次用户创建要播放的控制台应用程序实例时,它都会与服务器连接。 (等待 webSocket.ConnectAsync(new Uri("ws://localhost:xxx"), CancellationToken.None);)。

我有一个 websocketmiddlewear 类来接受 websocket 请求和一个管理器类,我在其中处理 websockets 请求。一切正常,除非用户退出控制台游戏。例如,当我从控制台(cmd)按“x”时,我收到以下错误

远程方未完成就关闭了 WebSocket 连接 亲密握手。

在下一行

WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); 

为什么代码没有处理错误以及如何修复它?

ConnectionManagerService.cs

 public async Task Receive(WebSocket socket)
        {
            var buffer = new byte[1024 * 4];

            while (socket.State == WebSocketState.Open)
            {
                WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);


               if (result.MessageType == WebSocketMessageType.Text)
                {
                    Console.WriteLine($"Receive->Text");      
                    return;   
                }
                else if (result.MessageType == WebSocketMessageType.Close)
                {
                    string id = _sockets.FirstOrDefault(s => s.Value == socket).Key;
                    //Console.WriteLine($"Receive->Close on: " + id);

                    _sockets.TryRemove(id, out socket);
                    Console.WriteLine("Managed Connections: " + _sockets.Count.ToString());

                    await socket.CloseOutputAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
                    return;
                }
            }
        }
 

WebsocketMiddleware.cs

        }
        public async Task Invoke(HttpContext context)
        {
            var isSocketRequest = context.WebSockets.IsWebSocketRequest;
            if (isSocketRequest)
            {
                WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();   
                _manager.AddSocket(socket);    
                await _manager.Receive(socket);

            }
            else
            {
                await _next(context);
            }
        }

【问题讨论】:

  • 好吧,如果您提到为什么在客户端关闭连接时会出现该错误,请考虑将代码移动到 try-catch 块中并以某种方式处理它,因为客户端套接字会在以下情况下抛出异常它被关闭了。

标签: c# asp.net websocket handshake


【解决方案1】:

发生这种情况是因为您只处理正常连接断开连接。客户端可能只是断开连接,而您将在 read/write 操作中间得到很大的ol SocketIO Exception

考虑将您的 Socket 操作包装在 try-catch 中,并随心所欲地处理它们。

public async Task Receive(WebSocket socket)
        {
            var buffer = new byte[1024 * 4];
            try{
                while (true) 
                {
                    WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        Console.WriteLine($"Receive->Text");      
                        return;   
                    }
                    else if (result.MessageType == WebSocketMessageType.Close)
                    {
                    string id = _sockets.FirstOrDefault(s => s.Value == socket).Key;
                    //Console.WriteLine($"Receive->Close on: " + id);

                    _sockets.TryRemove(id, out socket);
                    Console.WriteLine("Managed Connections: " + _sockets.Count.ToString());

                    await socket.CloseOutputAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
                    return;
                    }
                } 
            } catch(Exception ex){   //not so graceful disconnect
                 _sockets.TryRemove(id, out socket);
                    //deal with closed connection 
                    //maybe reconnect ?
            }
        }

【讨论】:

    猜你喜欢
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    • 2016-05-25
    • 2012-10-20
    • 2015-04-30
    • 1970-01-01
    相关资源
    最近更新 更多