通訊觀察線程是個有意思,又是非常實用的功能。
斷線重連具體怎么實現呢,很多人都實現過,那么TouchSocket等幾個通訊組件中也包含有,都是可以拿來就用。只是,對于高級用戶和特別細節操作要求的,是會自定義特別的超時斷線業務規則。
首先要有三個方法, start, stop和Restart
/// <summary>
/// 啟動
/// </summary>
public bool Start()
{try{//先執行ping 命令KeepServer = true;IPAddress ip = IPAddress.Parse(ComPara.ServerIP);IPEndPoint ipep = new IPEndPoint(ip, ComPara.Port);Tcpsocket.Connect(ipep);processor = new Thread(Communication);processor.IsBackground = true; processor.Start();return true;}catch (Exception ex){KeepServer = false; //ex.LogError();return false;}finally{this.communicationobserve_timer.Enabled = true;}
}/// <summary>
/// 停止服務
/// </summary>
public bool Stop()
{try{IsStop = true;this.communicationobserve_timer.Enabled = false;KeepServer = false;Tcpsocket.Close();Tcpsocket.Dispose();if (processor != null ) {processor.Abort();//解決線程過多情況,因為線程執行Abort,狀態是AbortRequested,還是會存在繼續執行while (processor.ThreadState != ThreadState.Aborted){ Thread.Sleep(100); }LogHelper.WorkAndInfo($"LB600 停止服務 Stop();");}return true;}catch //(Exception ex){ //ex.LogError();return false;}
}/// <summary>
/// 重新啟動
/// </summary>
protected bool ReStart()
{ try{KeepServer = true; //return Start();IPAddress ip = IPAddress.Parse(ComPara.ServerIP);IPEndPoint ipep = new IPEndPoint(ip, ComPara.Port);Tcpsocket.Connect(ipep); //IP和端口processor = new Thread(Communication);processor.IsBackground = true;processor.Start();//DelegateState.InvokeDispatchStateEvent($" {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")} {this.DeviceCode}號機器人,恢復連接成功!");//Comm.Speak($" {this.DeviceCode}號機器人,啟動重連中");return true;}catch //(Exception ex){KeepServer = false; //ex.LogError();return false;}
}
第二,要有Reconnect()方法
/// <summary>/// 重新創建連接/// </summary>public void ReConnect() {try{if (Init()){ if (ReStart()){LastConnectTime = DateTime.Now; //LastRecTime 在有反饋時才記錄Comm.Speak($"{DeviceCode}號設備,掉線后重連成功!");}}}catch (Exception ex){LogHelper.Error("嘗試連接" + $" 將在3秒后重新嘗試連接...", ex); }}
最重要的是最后這個通訊的超時監測,這里設置就是重聯達到的條件,至于兩個超時變量如下面定義:
/// <summary>
/// 通訊狀態觀察
/// </summary>
private void CommunicationObser(object sender, ElapsedEventArgs e)
{try{communicationobserve_timer.Enabled = false;//if (Monitor.TryEnter(lockobj, TimeSpan.FromSeconds(1))){//先判斷 機器人是否已經掉線if (LastRecLong > 2) //調試時修改為300, 默認1秒,{//如果接受消息時間已經大于1秒,則認為掉線了if (LastConnectLong > 3) //調試時修改為500, 默認3秒{ //如果車子掉線且連接時間超過3秒則需要重連LogHelper.WriteSendAGVMessLog($"重連 {DeviceCode}號"); //調試時暫時注釋掉//ReConnect(); 添加了LastRecTime = DateTime.Now;LastRecTime = DateTime.Now;Comm.Speak($"{DeviceCode}號,掉線后嘗試重連");ReConnect();}}}}catch (Exception ex){ LogHelper.Error($"觀察線程異常:{ex.Message}", ex);}finally{communicationobserve_timer.Enabled = true;}
}/// <summary>/// 最后一次重新連接的時間/// </summary>public DateTime LastConnectTime { get; set; }/// <summary>/// 距最后一次重連接的時長(秒)/// </summary>public double LastConnectLong{get{return (DateTime.Now - LastConnectTime).TotalSeconds;}}