C# Определить, когда ClientWebSocket отключен (закрыт)

После долгих поисков я прихожу к вам, чтобы помочь мне.

У меня есть приложение WPF, используйте класс ClientWebSocket (используя System.Net.WebSockets) для подключения к серверу WebSocket (NodeJS). Мое приложение запускает фоновое приложение Windows, оно подключается сначала, а затем, с интервалом в 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();
        }      
    }
}

За любые предложения я буду очень благодарен. Я действительно застрял в этой точке

2 ответа

Решение

Я решил свою проблему, поэтому я отвечаю на свой вопрос. Добавляя "финал" к try-catch метода "connect_socket":

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

Вы используете System.Threading.Timer, который запускает timer_callback в потоке пула потоков. Таким образом, любые исключения, выданные timer_callback в обратном вызове таймера, будут проглочены. Так что исключение web_socket.ConnectAsync когда вы потеряете соединение, будет также проглочен.

Также попробуйте проверить сообщение о закрытии сокета.

 var res = await webSocket.ReceiveAsync(segment, cancellation);
 if (res.MessageType == WebSocketMessageType.Close)
     return false;
Другие вопросы по тегам