[ASP.NET][SignalR] 悠閒 Coding 系列(一) - 認識 SignalR 建立 realtime 網頁(含完整程式碼下載)


最近打算利用假日或是空弦時間讓自己學些平常工作上用不到的東西,也算是讓自己增廣見聞吧,至於為什麼會叫做「悠閒 Coding 系列」呢?因為個人覺得學習就是應該是輕輕鬆鬆的,反而在緊繃的情況下學會的東西真的沒辦法扎根。看最近點部落上 SignalR 文章還滿火紅的,尤其是 饅頭的一系列 SignalR文章 ,所以首戰篇我們就來個 SignalR 實戰練習吧,剛好過些日子台中 Study4 的月份主題也會介紹到 SingnalR 這方面的應用,趁這個機會寫個文章記錄自己的學習歷程。

前言

最近打算利用假日或是空弦時間讓自己學些平常工作上用不到的東西,也算是讓自己增廣見聞吧,至於為什麼會叫做「悠閒 Coding 系列」呢?因為個人覺得學習就是應該是輕輕鬆鬆的,反而在緊繃的情況下學會的東西真的沒辦法扎根。看最近點部落上 SignalR 文章還滿火紅的,尤其是 饅頭的一系列 SignalR文章 ,所以首戰篇我們就來個 SignalR 實戰練習吧,剛好過些日子台中 Study4 的月份主題也會介紹到 SingnalR 這方面的應用,趁這個機會寫個文章記錄自己的學習歷程。

認識 SignalR

以往在建置網站時如果希望建立即時(realtime)的網站,通常都是透過 Client 定時重整頁面或是定時利用 Ajax 跟 Server 端要資料,但這樣的方法可能會造成 Server 的 Loading 太重,而且那並不合乎我們即時的觀念,應當是當 Server 更新時就 "主動" 發送訊息給 Client 端來做更新,才能符合所謂的 RealTime 網站。而 SignalR 主要功能就是協助我們解決這些問題,當然在 SignalR 之前也有許多 Solution 可以來解決這項問題,像是 Html 5 的 Server Side 與 Web Socket 方法、 以及其他像是 Long Polling 等 ,往往在實作上不是太複雜不然就是對於瀏覽器支援度不佳,而 SignalR 是基於 .Net 平台上能快速建置出支援即時通訊(real-time)的應用程式的一種 Solution 。

想像一下股票的即時資訊網站,我們希望獲得的是最即時且快速的資訊,如果我們每秒都跟 Server 端要一次資料,一個人的時候會沒什麼感覺,倘若今天是100個人同時取得股票資訊,Server 一定無法負荷,產生的結果大概就像前陣子很夯的「鍵盤攻擊」那樣.... ,寫了一支程式打自己的 Server。透過 SingnalR 則可以完全解決這個問題,運作原理就是當使用者進入頁面時就馬上建立起一條連線通道,這條通道就是負責來做資料的傳遞 ,並當 Server 更新時就馬上透過這個管道將資料傳遞給前端頁面做更新,而不用每次都跟 Server Request 資料。

另外在小朱前輩的文章也有寫到,SingalR 在做資料傳遞時是以 JSON 為基礎,所以也可以相容大多的瀏覽器而且也非常輕量化,然而如果是較老的瀏覽器(IE6、IE7)就無法直接支援,可能還是得透過外部的 JSON Parser 來處理。

透過 SignalR 建立即時聊天室

這邊我們就已一個最簡單的聊天室來跟大家介紹,而需求也非常清楚就是聊天嘛 ~ 當使用者進入聊天後建立起連線,當使用者發送訊息時,所有在聊天室的人都可以即時同步訊息。

而開始之前為了嚇跑大家,我們先來點輕鬆的,照著步驟做完後的完成圖如下:

1.一開始我們建立一個 ASP.NET 空白 Web Application 專案。

2.透過 NuGet 來安裝 SignalR 套件

3.透過 Nuget 好處就是會自動幫我們安裝需要的參考以及相關檔案。

5.新增一個 SignalR Hub 類別且命名為 codingChatHub.cs ,用來實作 Server 端的程式。

6.我們稍微修改一下 Hub 的程式碼:


    public class codingChatHub : Hub
    {
        public void Hello(string name)
        {
            //這邊會傳入name參數
            //呼叫所有連線狀態中頁面上的 javascript function => hello
            //透過server端呼叫client的javascript function

            string message = "歡迎使用者" + name + "加入聊天室";
            Clients.All.hello(message);
        }

        public void SendMessage(string name, string message)
        {
            //這邊會傳入name和message參數
            //並且會呼叫所有連線狀態中頁面上的 javascript function => sendAllMessage
            //透過server端呼叫client的javascript function

            message = name + ":" + message;
            Clients.All.sendAllMessge(message);
        }
    }

7.再來新增一個 Global Appication class ,中文為全域應用程式類別。

8.而接著我們在 Global 裡的 Application_Start 裡面來註冊 SignalR hub 的的預設路由(~/signalr/hubs)。

先引用


using System.Web.Routing;
using Microsoft.AspNet.SignalR;

接著在 Application_Start 裡新增程式碼:


        protected void Application_Start(object sender, EventArgs e)
        {
            //註冊 hub 的的預設路由:~/signalr/hubs
            RouteTable.Routes.MapHubs();
        }

上面的部份我們實作了一個 Server 端的 Hub 之後,接下來繼續看看 Client 如何與我們的 Server 端互動。

9.再來我們在專案上「按右鍵」新增 Web Form 取名為 chat.aspx 功能當然就是讓使用者輸入、接收訊息的頁面,然後我們稍微設計一下頁面,程式碼如下:


<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>SignalR 聊天室</title>
    <style>
        #userName {
            display: none;
            color: red;
        }
    </style>
</head>
<body>
    <p id="userName">Hi! </p>
    <div id="messageBox">
        <p>聊天室內容</p>
        <ul id="messageList"></ul>
    </div>
    <div>
        <input type="text" id="message" />
        <input type="button" id="send" value="發送" />
    </div>
</body>

Javascript 程式碼:


    <%-- 引用 jQuery 的參考--%>
    <script src="/Scripts/jquery-1.6.4.min.js"></script>
    <%--引用 SignalR 的參考--%>
    <script src="/Scripts/jquery.signalR-1.1.1.min.js"></script>

    <%--這邊滿重要的,這個參考是動態產生的,當我們build之後才會動態建立這個資料夾,且需引用在jQuery和signalR之後--%>
    <script src="/signalr/hubs"></script>

    <script type="text/javascript">
        var userID = "";

        $(function () {

            while (userID.length == 0) {
                userID = window.prompt("請輸入使用者名稱");
                if (!userID)
                    userID = "";
            }
            $("#userName").append(userID).show();

            //建立與Server端的Hub的物件,注意Hub的開頭字母一定要為小寫
            var chat = $.connection.codingChatHub;

            //建立連線後,我們接著來定義client端的function來讓Server端的hub呼叫。

            chat.client.hello = function (message) {
                $("#messageList").append("<li>" + message + "</li");
            }

            chat.client.sendAllMessge = function (message) {
                $("#messageList").append("<li>" + message + "</li");
                $("#message").val('');
            }

            //將連線打開
            $.connection.hub.start().done(function () {
                //當連線完成後,呼叫Server端的hello方法,並傳送使用者姓名給Server
                chat.server.hello(userID);
            });;

            $("#send").click(function () {
                //呼叫Server端的sendMessage方法,並傳送使用者姓名及訊息內容給Server
                chat.server.sendMessage(userID, $("#message").val());
            });

        });
    </script>

重點整理

  • 需先引用 jQuery 及 signalR ,再來引用 <script src="/signalr/hubs"></script>,這個參考在debug模式時是不會出現的,要等到專案build後才會動態產生。
  • 透過 $.connection.hubName 來建立 hub 的物件,但需注意第一個字母需為小寫字母
  • 若要由 client 端呼叫 server 端的方法需使用:chat.server.method
  • 而要建立 client 端方法,讓 server 端呼叫的 function ,則要利用 chat.client.method = function(data) { };
  • 透過 chat.server 呼叫 server 端方法時,方法首字需為小寫字母,並且需在 $.connection.hub.start() 建立連線之後

程式碼下載

SignalR.rar

總結

最後我們分別用多個瀏覽器進入,就是一個即時的聊天室了,而有使用者進入聊天室也可以即時通之,整個簡單的聊天室 Code 也不超過100行就解決了 ,比較需要注意的是在寫 chat.server.{method} 時記得方法開頭需為小顯,透過微軟的 SignalR 來建立超即時(real-time)的網頁一點都不困難,另外 SignalR 的應用不僅僅局限於 ASP.NET 上,而是支援整個 .Net Framework 的平台都,也不限於 Hosting 的應用程式,另外打開開發者工具也可以看到 hub 一直處於連線的狀態,有興趣的讀者也歡迎把Code下載回去玩玩看 ~。


參考連結

新手發文,如有錯誤煩請告知,感謝。
如果喜歡我的文章請按推薦,有任何問題歡迎下面留言~~~

 

 

簽名:

學習這條路很廣,喜歡什麼技術不重要,重要的是你肯花時間去學習