【c#源碼】基於TCP通訊的用戶端斷線重連

來源:互聯網
上載者:User

標籤:

源碼下載

在CS程式中,斷線重連應該是一個常見的功能。

此處的斷線重連主要指的是伺服器端因為某種故障,伺服器端程式或者系統進行了重新啟動,用戶端能夠自動探測到伺服器端掉線,並嘗試重新進行串連

本程式基於來自英國的開源c#通訊架構的networkcomms(2.3.1版本)

先看一下效果

初始狀態:

當伺服器端程式關閉後,用戶端會自動探測到,並在用戶端顯示相關資訊

然後,我們設定為每隔5秒重連一次,可以自訂設定重連的次數,比如說重連50次,如果還沒有重連成功,則放棄重連

然後我們重新啟動伺服器端,用戶端會顯示重連成功.

具體步驟如下:

需要修改幾處NetworkComms2.3.1通訊架構中的代碼

第一步:修改ConnectionInfo類的NoteConnectionShutdown方法

該方法原來是:

   internal void NoteConnectionShutdown()        {            lock (internalLocker)                ConnectionState = ConnectionState.Shutdown;        }
View Code

修改後為: 

   private bool reconnectFlag = false;        /// <summary>        /// 是否為重串連模式        /// </summary>        public bool ReconnectFlag        {            get { return reconnectFlag; }            set { reconnectFlag = value; }        }        /// <summary>        /// Note this connection as shutdown        /// </summary>        internal void NoteConnectionShutdown()        {            lock (internalLocker)                ConnectionState = ConnectionState.Shutdown;            //添加以下代碼  初始狀態為False  觸發串連狀態改變事件            if (reconnectFlag == false)            {                StateChanged.Raise(this, new StringEventArgs("串連出現異常"));            }        }        //添加狀態改變事件         public event EventHandler<StringEventArgs> StateChanged;

 

第二步:在NetworkComms庫類中添加相關的代碼如下:

using System;using System.Collections.Generic;using System.Text;using NetworkCommsDotNet.Tools;namespace NetworkCommsDotNet{    public static class Extensions    {        public static void Raise<T>(this EventHandler<T> handler, object sender, T args) where T : EventArgs        {            if (handler != null)                handler(sender, args);        }    }    public class StringEventArgs : EventArgs    {        public StringEventArgs(string text)        {            Text = text;        }        public string Text { get; set; }    }  }namespace System.Runtime.CompilerServices{    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]    public sealed class ExtensionAttribute : Attribute { }}
相關代碼

第三步:在NetworkComms靜態類中添加如下方法:

 public static void ClearDic()        {            lock (globalDictAndDelegateLocker)            {                allConnectionsById.Clear();                allConnectionsByEndPoint.Clear();                oldNetworkIdentifierToConnectionInfo.Clear();            }        }

如果您使用的是V3版本,代碼稍微變化:

 public static void ClearDic()        {            lock (globalDictAndDelegateLocker)            {                allConnectionsByIdentifier.Clear();                allConnectionsByEndPoint.Clear();                oldNetworkIdentifierToConnectionInfo.Clear();            }        }
V3

用戶端代碼:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using NetworkCommsDotNet;using DPSBase;using System.Net;using System.Threading;namespace AppClient{    public partial class Form1 : Form    {        //串連資訊類        public ConnectionInfo connnectionInfo = null;        //串連類        Connection connection;        public Form1()        {            InitializeComponent();                  }        //在表單上顯示新資訊        void Form_ConnectionStatusNotify(object sender, StringEventArgs e)        {            if (this.InvokeRequired)            {                this.Invoke(new EventHandler<StringEventArgs>(this.Form_ConnectionStatusNotify), sender, e);            }            else            {                lblLink.Text = e.Text;                lblLink.ForeColor = Color.Blue;            }        }        private bool ServerNotifyClose = false;        public event EventHandler<StringEventArgs> ConnectionStatusNotify;        void connnectionInfo_StateChanged(object sender, StringEventArgs e)        {            //如果不是伺服器通知關閉,則自動重連,如果是伺服器通知關閉,則不作處理            //本Demo中沒有使用ServerNotifyClose            if (ServerNotifyClose == false)            {                //更新串連資訊類  設定為重連模式                connnectionInfo.ReconnectFlag = true;                                 ConnectionStatusNotify.Raise(this, new StringEventArgs("可能由於伺服器的故障,與伺服器端的串連已斷開"));                int num = 0;                int retryCount = 30;                int retrySpanInMSecs = 5000;                do                {                    try                    {                        NetworkComms.ClearDic();                        connection = TCPConnection.GetConnection(connnectionInfo);                                                                           ConnectionStatusNotify.Raise(this, new StringEventArgs("重連成功"));                        connnectionInfo.ReconnectFlag = false;                        break;                    }                    catch (Exception ex)                    {                        num++;                        if (num < retryCount)                        {                                                        ConnectionStatusNotify.Raise(this, new StringEventArgs("進行中第" + num + "次重連"));                            Thread.Sleep(retrySpanInMSecs);                        }                    }                }                while (num < retryCount);            }        }                 private void button1_Click(object sender, EventArgs e)        {             connnectionInfo = new ConnectionInfo(txtIP.Text, int.Parse(txtPort.Text));            //如果不成功,會彈出異常資訊            connection = TCPConnection.GetConnection(connnectionInfo);            button1.Enabled = false;            button1.Text = "串連成功";            //訂閱串連資訊類中的串連狀態改變事件            connnectionInfo.StateChanged += new EventHandler<StringEventArgs>(connnectionInfo_StateChanged);            this.ConnectionStatusNotify += new EventHandler<StringEventArgs>(Form_ConnectionStatusNotify);        }        //擷取水果相關資訊        private void button2_Click(object sender, EventArgs e)        {            if (listBox1.SelectedIndex > -1)            {                 string resMsg = connection.SendReceiveObject<string>("ReqFruitEngName", "ResFruitEngName", 5000, listBox1.Text);                                 MessageBox.Show("您選擇的水果的英文名稱是:" + resMsg);            }            else            {                MessageBox.Show("請選擇一項");            }        }        private void Form1_FormClosing(object sender, FormClosingEventArgs e)        {            this.Dispose();        }           }}
用戶端代碼

伺服器端無需額外的設定。

至此,我們的工作已經完成。

祝大家工作順利 

 

【c#源碼】基於TCP通訊的用戶端斷線重連

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.