依據網路上的討論,SignalR Client本身已內建重連機制,連線中斷後會自動重連,理論上不需要額外費心寫Code處理。不過我還是決定實測一下,確保程式行為如同預期比較安心。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SignalR;
using SignalR.Hubs;
using System.Threading.Tasks;
namespace HubWeb.Models
{
public class CommHub : Hub, IDisconnect, IConnected
{
//連線關閉時觸發
public Task Disconnect()
{
return null;
}
//連線建立時觸發
public Task Connect()
{
string cid = Context.ConnectionId;
Clients[cid].ShowMessage("Hello");
return null;
}
//重新連線時觸發
public Task Reconnect(IEnumerable<string> groups)
{
string cid = Context.ConnectionId;
Clients[cid].ShowMessage("Reconnect");
return null;
}
//偵測連線狀態
public void HeartBeat()
{
string cid = Context.ConnectionId;
Clients[cid].ShowMessage(
string.Format("HearBeat@{0:mm:ss}", DateTime.Now));
}
}
}
Client端的邏輯為: 宣告連線、建立Proxy、註冊"ShowMessage”事件Console.WriteLine傳入的訊息、接著connection.Start()啟動連線、使用無窮迴圈定期呼叫HeartBeat(為求簡化沒寫跳出邏輯,測到高興後使用Ctrl-C大絕結束程式)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using SignalR.Client.Hubs;
using System.Threading.Tasks;
namespace ConsoleClient
{
class Program
{
static void Main(string[] args)
{
//連線SignalR Hub
var connection = new HubConnection("http://localhost:26217/");
IHubProxy commHub = connection.CreateProxy("CommHub");
//顯示Hub傳入的文字訊息
commHub.On("ShowMessage", msg => Console.WriteLine(msg));
//建立連線,連線建立完成後向Hub註冊識別名稱
var init = connection.Start().ContinueWith<bool>(task =>
{
//若連線失敗,顯示錯誤並return false;
if (task.IsFaulted)
{
foreach (var e in
task.Exception.Flatten().InnerExceptions)
Console.WriteLine("Error: " + e.Message);
return false;
}
//若未出錯,則return true 通過檢查後才能繼續執行
return true;
});
//利用Task.Result的同步化等待,待連線完成後才續持
if (!init.Result)
return;
//持續執行,如要結束就用Ctrl-Break大絕
while (true)
{
var hb =
commHub.Invoke("HeartBeat").ContinueWith<bool>(task =>
{
//出錯時傳回false; 否則傳回true;
if (task.IsFaulted)
{
foreach (var ex in
task.Exception.Flatten().InnerExceptions)
{
Console.WriteLine("Error: {0}", ex.Message);
}
return false;
}
return true;
});
if (!hb.Result)
Console.WriteLine("HeartBeat Failed");
Thread.Sleep(2000);
}
}
}
}
實測結果如下圖。連線後Connect事件被觸發回呼Client顯示"Hello",接著開始每兩秒顯示一次無窮無盡的HeartBeat訊息。故意停止CommHub所在的IIS Express,則如預期出現"Unable to connect to the remote server”及心跳失敗錯誤訊息,接著重新啟動IIS Express,薑薑薑薑~ 心跳目動恢復,Reconnect事件也被觸發,驗證了SignalR的自動重連功能很好很強大,可以安心地應用在系統中嚕!