Как продолжать пытаться подключиться к веб-сокету, даже если было достигнуто максимальное число повторов для подключения? - PullRequest
0 голосов
/ 25 октября 2018

В настоящее время я использую приложение на C #, которое должно подключаться через веб-сокет к программному обеспечению, написанному на C ++.Приложение C # - это клиент, программное обеспечение C ++ - сервер.Я хотел бы, чтобы приложение C # пыталось повторно подключаться к веб-сокету каждые 5 секунд, если оно не подключено.В настоящее время я использую websocket-sharp.

На данный момент это мой код:

using System;
using System.Threading;
using WebSocketSharp;

namespace ConsoleApp1
{
    class Program
    {
         static void Main(string[] args)
         {
            using (var ws = new WebSocket("ws://192.168.1.25:50000"))
            {
                ws.OnMessage += (sender, e) =>
                {
                    Console.WriteLine("Message received : " + e.Data);
                    if (e.Data == "alreadyConnected")
                    {
                        ws.Send("forceConnect");
                    }
                    if (e.Data == "connexionEstablished")
                    {
                        ws.Send("Hello server");
                    }
                };

                ws.OnOpen += (sender, e) =>
                {
                    Console.WriteLine("Connexion has been established");
                    ws.Send("some message");
                };

                ws.OnClose += (sender, e) =>
                {
                    Console.WriteLine("Connexion has been lost");
                    if (!e.WasClean)
                    {
                        if (!ws.IsAlive)
                        {
                            Thread.Sleep(5000);
                            ws.Connect();
                        }
                    }
                };

                ws.OnError += (sender, e) =>
                {
                    Console.WriteLine("Connexion has led to an error");
                };

                ws.Connect();
                Console.ReadKey(true);
            }
        }
    }
}

Но после 10 неудачных попыток я получаю сообщение об ошибке "Серия повторных подключений не удалась".Это связано с максимальным количеством повторных попыток, фиксированных в websocket-sharp.После того, как я получил это сообщение, я не нашел способа (ни пытаться в одиночку, ни искать в интернете) продолжать попытки восстановить соединение.Кто-нибудь знает, как я могу это сделать?

Если бы кто-то мог помочь, я был бы очень благодарен :) Хорошего дня!

1 Ответ

0 голосов
/ 03 января 2019

Ниже приведен высокоуровневый код, который я использую для постоянной попытки восстановить соединение, если по какой-либо причине соединение между хостом и клиентом прерывается.Приведенный ниже фрагмент сам по себе не проверен, но я использую аналогичные конструкции в производственном коде.

Дополнительным требованием является библиотека WebSocketSharp , которая содержит все элементы, которые упрощают кодирование Websocket.

using System;
using System.Text;
using System.Net.Sockets;
using System.Collections.Generic;

using WebSocketSharp;



namespace Application1
{
    class Program
    {


        static void Main(string[] args)
        {

            // Locals
            string host         = "127.0.0.1";
            int port            = 8080;
            int Frq_Reconnect   = 10000;
            WebSocket ws;

            // Start WebSocket Client
            ws              = new WebSocket(string.Format("ws://{0}:{1}", host, port));
            ws.OnOpen       += new EventHandler(ws_OnOpen);
            ws.OnMessage    += new EventHandler<MessageEventArgs>(ws_OnMessage);
            ws.OnError      += new EventHandler<ErrorEventArgs>(ws_OnError);
            ws.OnClose      += new EventHandler<CloseEventArgs>(ws_OnClose);


            // Connection loop
            while (true)
            {
                try
                {
                    if (!ws.IsAlive)
                    {
                        ws.Connect();
                        if (ws.IsAlive)
                        {
                            ws.Send(JsonConvert.SerializeObject(json, Formatting.None));
                        }
                        else
                        {
                            Console.WriteLine(string.Format("Attempting to reconnect in {0} s", Frq_Reconnect / 1000));
                        }
                    }
                }
                catch (Exception e)
                {
                    string errMsg = e.Message.ToString();
                    if (errMsg.Equals("The current state of the connection is not Open."))
                    {// remote host does not exist
                        Console.WriteLine(string.Format("Failed to connect to {0}:{1}", host, port));
                    }
                    if (errMsg.Equals("A series of reconnecting has failed."))
                    {// refusal of ws object to reconnect; create new ws-object

                        ws.Close();

                        ws             = new WebSocket(string.Format("ws://{0}:{1}", host, port));
                        ws.OnOpen     += new EventHandler(ws_OnOpen);
                        ws.OnMessage  += new EventHandler<MessageEventArgs>(ws_OnMessage);
                        ws.OnError    += new EventHandler<ErrorEventArgs>(ws_OnError);
                        ws.OnClose    += new EventHandler<CloseEventArgs>(ws_OnClose);

                    }
                    else
                    {// any other exception
                        Console.WriteLine(e.ToString());
                    }

                }


            // Callback handlers
            void ws_OnClose(object sender, CloseEventArgs e)
            {
                Console.WriteLine("Closed for: " + e.Reason);
            }

            void ws_OnError(object sender, ErrorEventArgs e)
            {
                Console.WriteLine("Errored");
            }

            void ws_OnMessage(object sender, MessageEventArgs e)
            {
                Console.WriteLine("Messaged: " + e.Data);
            }

            void ws_OnOpen(object sender, EventArgs e)
            {
                Console.WriteLine("Opened");
            }



        }// end      static void Main(...)



    }
}

Это ловит исключение времени ожидания объекта WebSocket, очищает текущий экземпляр объекта, а затем создает новый.После этого общий цикл соединения продолжается.

Для меня вышеизложенное позволяет мне пытаться повторно подключаться всю ночь ...

Далее, структура этого кода гарантирует отсутствие переполнения стека.после длинной серии попыток соединения.Например, я видел людей, обрабатывающих прерывания соединения в обработчике события On_Close.В конечном итоге это не работает, потому что такой подход приводит к обновленной реализации объекта WebSocket и в конечном итоге приводит к истощению системных ресурсов.

...