[C#]ConsoleApplication 環境下使用 SignalR

  • 9257
  • 0

摘要:[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

 

 

※在此感謝所有的幫助者,感謝~