即使已达到连接的最大重试次数,如何保持与websocket的连接?

时间:2018-10-25 08:51:49

标签: c# websocket-sharp

我当前正在使用一个C#应用程序,该应用程序需要通过websocket连接到已用C ++编码的软件。 C#应用程序是客户端,C ++软件是服务器。 我希望C#应用程序尝试每5秒重新连接到websocket(如果未连接)。我目前正在使用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 :(得分:0)

以下是一些高级代码,如果主机和客户端之间的连接由于某种原因被中断,我将不断尝试重新连接它们。下面的代码片段本身未经测试,但是我在生产代码中使用了类似的结构。

另外一个要求是WebSocketSharp library,其中包含使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对象的更新实例化,并最终导致系统资源的耗尽。