摘要:[C#]ConsoleApplication 環境下使用 SignalR
下面為體驗 ConsoleApplication 環境下使用 SignalR 情境。接下來直接實作一次。
Server 端的部分
步驟1.
先透過 套件管理器主控台 去安裝 Microsoft.AspNet.SignalR.SelfHost,
直接輸入PM> Install-Package Microsoft.AspNet.SignalR.SelfHost
並透過 套件管理器主控台 去安裝 Microsoft.Owin.Cors,
直接輸入PM> Install-Package Microsoft.Owin.Cors
步驟2.
輸入下面的程式碼
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
//Server 端
namespace Server
{
internal class Program
{
private static void Main(string[] args)
{
string url = "http://localhost:5051";//設定 SignalR Hub Server 對外的接口
using (WebApp.Start(url))//啟動 SignalR Hub Server
{
Console.WriteLine("Server running on {0}", url);
Console.ReadLine();
}
}
}
/// <summary>
/// 啟動 SignalR Hub 所需
/// </summary>
internal class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
/// <summary>
/// 保存Client識別資料的物件
/// </summary>
public class ClientInfo
{
public string ConnId { get; set; }
public string ClientName { get; set; }
}
/// <summary>
/// Server Hub
/// </summary>
public class MyHub : Hub
{
/// <summary>
/// 紀錄目前已連結的 Client 識別資料
/// </summary>
public static Dictionary<string, ClientInfo> CurrClients = new Dictionary<string, ClientInfo>();
/// <summary>
/// 提供Client 端呼叫
/// 功能:對全體 Client 發送訊息
/// </summary>
/// <param name="message">發送訊息內容</param>
public void SendMsg(string message)
{
string connId = Context.ConnectionId;
lock (CurrClients)
{
if (CurrClients.ContainsKey(connId))
{
Clients.All.ReceiveMsg(CurrClients[connId].ClientName, message);//呼叫 Client 端所提供 ReceiveMsg方法(ReceiveMsg 方法由 Client 端實作)
}
}
}
/// <summary>
/// 提供 Client 端呼叫
/// 功能:對 Server 進行身分註冊
/// </summary>
/// <param name="clientName">使用者稱謂</param>
public void Register(string clientName)
{
string connId = Context.ConnectionId;
lock (CurrClients)
{
if (!CurrClients.ContainsKey(connId))
{
CurrClients.Add(connId, new ClientInfo { ConnId = connId, ClientName = clientName });
}
}
Clients.All.NowUser(CurrClients);
}
/// <summary>
/// Client 端離線時的動作
/// </summary>
/// <param name="stopCalled">true:為使用者正常關閉(離線); false: 使用者不正常關閉(離線),如連線狀態逾時</param>
/// <returns></returns>
public override Task OnDisconnected(bool stopCalled)
{
string connId = Context.ConnectionId;
lock (CurrClients)
{
if (CurrClients.ContainsKey(connId))
{
CurrClients.Remove(connId);
}
}
Clients.All.NowUser(CurrClients);//呼叫 Client 所提供 NowUser 方法(ReceiveMsg 方法由Client 端實作)
stopCalled = true;
return base.OnDisconnected(stopCalled);
}
}
}
Clinet 端的部分
步驟1.
透過 套件管理器主控台 去安裝 Microsoft.AspNet.SignalR.Client,
直接輸入PM> Install-Package Microsoft.AspNet.SignalR.Client
步驟2.
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
//Clinet 端
namespace Client
{
/// <summary>
/// 保存Client識別資料的物件
/// </summary>
public class ClientInfo
{
public string ConnId { get; set; }
public string ClientName { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
//輸入使用者稱謂
Console.Write("Please input client name: ");
string clientName = Console.ReadLine();
//與SignalR Hub Server 連線
var connection = new HubConnection("http://localhost:5051");
IHubProxy myHub = connection.CreateHubProxy("MyHub");//其名稱必須與 Server Hub 類別名稱一樣
//---實作(定義) Client 端方法----------------------------------------------------------------
//實作(定義) ReceiveMsg 方法
//功能:接收並顯示 Server Hub 傳入的文字訊息
myHub.On<string, string>("ReceiveMsg", (name, message) => Console.WriteLine("{0}- {1}", name, message));
//實作(定義) NowUser 方法
//功能:接收並顯示目前所有使用 Server Hub 的使用者
myHub.On<Dictionary<string, ClientInfo>>("NowUser", (currClients) => currClients.Values.ToList().ForEach(row => Console.WriteLine("目前已連線使用者: {0}",row.ClientName)));
//-------------------------------------------------------------------------------------------
//建立連線,連線建立完成後向 Server Hub 註冊使用者稱謂
connection.Start().ContinueWith(task =>
{
if (!task.IsFaulted)
{
//連線成功時呼叫 Server 端 Register 方法
myHub.Invoke("Register", clientName);//必須與 MyHub 的 Register 方法名稱一樣
}
else
{
throw new Exception("連線失敗!");
}
}).Wait();
//定時發送訊息給所有使用者()
new Task(() =>
{
while (true)
{
Thread.Sleep(1000);
myHub.Invoke("SendMsg", DateTime.Now.ToString());//必須與 MyHub 的 SendMsg 方法名稱一樣
}
}).Start();
//維持程式執行迴圈,直止輸入 colse 文字串
while (Console.ReadLine() != "colse") { }
Console.WriteLine("close...");
//結束與 SignalR Hub Server 之間的連線
connection.Stop();
}
}
}
啟動前設定
由於必須 先啟動Server 端 ConsoleApplication後,才能啟動Client端 ConsoleApplication ,因此必須在 方案 -> 屬性 做啟動順序的設定,如下圖(注意上下順序):
結果如下圖所示
主要參考:
利用SignalR實現遠端程式遙控功能 by 黑暗執行緒
SignalR 初體驗 by Frank's blog
Tutorial: SignalR Self-Host
※在此感謝所有的幫助者,感謝~