【问题标题】:c# Detect when ClientWebSocket is disconnected (closed)c#检测ClientWebSocket何时断开(关闭)
【发布时间】:2018-01-23 15:46:15
【问题描述】:

经过长时间的搜索,我来找你帮助我。

我有一个 WPF 应用程序,使用 ClientWebSocket 类(使用 System.Net.WebSockets)连接到 WebSocket 服务器(NodeJS)。我的应用程序正在运行背景 Windows 应用程序,它第一次连接,然后在 1 分钟的计时器内尝试重新连接(如果尚未连接)。但是当我禁用连接(网络连接)时,我的应用程序没有检测到它,所以每 1 分钟告诉我它已连接。我知道我的代码有问题,我不知道如何实现事件处理程序以在连接丢失(websocket 关闭)时得到通知。

我注意到当我连接到服务器时,我必须创建一个会话,然后我收到一个 session_id,现在我连接到了 websocket 服务器。

Class1 是一个库类,我使用 WebSockets 类

class1
{
    ClientWebSocket web_socket;
    bool connected = false;
    public async Task<bool> connect_socket()
    { 
        Object result_object;
        string session_id;
        try
        {
            if (connected == false)
            {
                web_socket = new ClientWebSocket();
                web_socket.Options.SetRequestHeader("headername", "headerValue");
                await web_socket.ConnectAsync(new Uri(" ... uri....."), CancellationToken.None);

                create_session();

                ArraySegment<byte> byte_received = new ArraySegment<byte>(new byte[1024]);
                WebSocketReceiveResult json_notify_result = await web_socket.ReceiveAsync(byte_received, CancellationToken.None);
                string string_notify = Encoding.UTF8.GetString(byte_received.Array);
                json_notify = JsonConvert.DeserializeObject<Dictionary<string, object>>(string_notify);

                if (json_notify.TryGetValue("result", out result_object))
                {
                    var result = JsonConvert.DeserializeObject<Dictionary<string, string>>((result_object).ToString());
                    if (result.TryGetValue("session_id", out session_id) && (string)session_id != null)
                        Debug.WriteLine("session_id = " + session_id);
                }
                 connected = true;
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
         return connected;
    }
}

在我的 Class2 中,我使用 Class1

Class2
{
    Class2()
    {
        InitializeComponent();
        timer = new System.Threading.Timer(timer_callback, null, 0, 60000);
    }
    public void timer_callback()
    {
        if (Class1.connected == false)
        {
            Class1.connect_socket().Wait();
        }      
    }
}

如有任何建议,我将不胜感激。 我真的被困在这一点上

【问题讨论】:

    标签: c# networking connection clientwebsocket system.net.websockets


    【解决方案1】:

    您正在使用 System.Threading.Timer,它在线程池线程上运行 timer_callback。所以定时器回调中抛出的任何异常 timer_callback 都会被吞掉。所以当你断开连接时web_socket.ConnectAsync 抛出的异常也会被吞掉。

    同时尝试检查套接字关闭消息。

     var res = await webSocket.ReceiveAsync(segment, cancellation);
     if (res.MessageType == WebSocketMessageType.Close)
         return false;
    

    【讨论】:

    • 谢谢你的回答,你能解释一下吗?我在哪里可以测试 WebSocketMessageType 是否为 Close ?
    • 检查消息是否为 Close 类型实际上是防止崩溃并要求重新打开连接的绝妙方法。
    【解决方案2】:

    我解决了我的问题,所以我回答自己的问题。通过在“connect_socket”方法的 try-catch 中添加“finaly”:

    finally
                {
                    Debug.WriteLine("\n"+ "Dispose websocket");
                    if (web_socket != null)
                        web_socket.Dispose();
                    state = WebsocketState.closed;
                    session_id = null;
                    Debug.WriteLine("\n" + "state of websocket is : " + state);
                }
    

    “状态”是一个用于代替“已连接”的变量,它取值:已关闭、正在连接、已连接。在第二类“Class2”中,我尝试在状态为“关闭”时进行连接

    if (Class1.state == "closed")
            {
                Class1.connect_socket().Wait();
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 2017-05-08
      • 2013-02-10
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      相关资源
      最近更新 更多