[.NET]SignalR簡介 - 建立 realtime 的網站

[.NET]SignalR簡介 - 建立 realtime 的網站

前言

一早起床後,在消化 RSS 的過程中,看到 Scott Hanselman 在 Russia TechDays 介紹 SignalR 的影片,一整個讓人很驚豔,馬上就想動手寫寫看。

由於我也是初學者,先把相關 Reference 列上來,有興趣的朋友可以直接參考官網或影片,應該會比我的文章清楚的多。

Reference : 

簡介

SignalR 的重點,就在於即時 (realtime) ,以往在設計網站的時候,基本上都是透過 client 頁面重新整理頁面、重送 request 或定時輪詢 server 端,以重新呈現即時的資料。但那根本不是即時,即時應該是 server 端一旦有了最新的資料,會主動通知 client 端更新資料的呈現。

但這樣的機制,往往得透過很多機制,很多複雜的設計,才有可能達成。

SignalR 則像撰寫 .NET Remoting 一般

  1. 在 server 端定義對應的 hub class。
  2. 在 client 定義 hub class 所對應的 proxy。
  3. 在 client 與 server間,建立一個不斷的connection。
  4. 接著 client 端可以呼叫 proxy object 的方法,也就是 server 端的方法,也就是送 request 給 server 端。
  5. server 端接收到 request 資料後,可以針對所有的 client 發送通知。

如果各位去下載 SignalR.Sample ,其例子就是股票的即時資訊,股票的資訊沒法子透過定時重新整理,那可能會虧死。如果每一秒都跟 server 送 request,那 server 一定會 loading 太重而炸掉。透過 SignalR,這不再是無解的問題。

有興趣的朋友,可以直接在 NuGet 的 Package Manager Console,輸入

install-package SignalR.Sample

 

即時聊天室範例

這邊跟著說明文件,來建立一個可即時對所有 client 送出,某人送出最新的訊息。

  1. 建立一個 ASP.NET 4.0 的 WebApplication or WebSite,官網上是使用 Web Application,我這邊則使用 WebSite 來示範。
  2. 在 NuGet 的Package Manager Console,輸入「install-package SignalR」,相關的參考檔案,如下圖所示:
    image
  3. 建立一個範例網頁: SignalR_Sample.aspx,供使用者可以透過網頁發送與接收聊天室訊息。
  4. 建立一個 Chat class,用來處理 client 發送的訊息,以及發送通知給所有 client 的處理。

接下來,來看網頁與 server 端的 hub 該怎麼設計。

 

實作

首先,設計一個最簡單的發送與接收訊息的畫面,程式碼如下:


    <div>
        <input type="text" id="message" />
        <input type="button" id="send" value="送出" />
        <div>
            聊天室內容:
            <br />
            <ul id="wholeMessages">
            </ul>
        </div>
    </div>

畫面:

image

接下來撰寫 server 端 Chat class 的內容:

image

幾個重點:

  1. HubName:這個 atttibute 代表 client 端要如何建立對應 server 端物件的 proxy object。透過 HubName , server 端的 class name才不會被 client 綁死。如果沒有設定,則會以 server 端 class name 為 HubName 預設值。
  2. 繼承 Hub:繼承 Hub 之後,很多對應的設計就都不用寫了,我們只需要把注意力放在 client 如何送 request 給 server的 hub , server 如何通知 client 即可。 Hub 上有一些屬性可以使用,請參考下圖:
    image
  3. public void SendMessage(string message) ,就像 WebService Method 或 PageMethod 一般, client 端透過 proxy object ,可以直接呼叫 server 端這個方法。後續會介紹到如何在頁面上使用。
  4. Clients property:代表所有有使用 Chat 的頁面。而 Clients 的型別是 dynamic ,因為要直接對應到 JavaScript 的物件。
  5. Clients.addMessage(message):代表 server 端呼叫 Clients 上的 addMessage 方法,也就是 JavaScript 的方法。
  6. 總結: Chat 物件負責的,就是當 client 端呼叫 SendMessage() 方法後,要把這個 message ,送給所有 client 頁面上呈現。以達到聊天室的功能。

Server 端的 Hub 物件設計好後,接著來看頁面上如何與 server 的 hub 物件互動。

頁面:


    <script src="Scripts/jquery-1.6.4.js" type="text/javascript"></script>
    <script src="Scripts/jquery.signalR-0.5.2.js" type="text/javascript"></script>
    <%--很重要的一個參考,一定要加,且在這一行之前,一定要先參考jQuery.js與signalR.js--%>
    <script src="../SignalR_WebSite/signalr/hubs" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {

            // 建立對應server端Hub class的物件,請注意joeyChat的第一個字母要改成小寫
            var chat = $.connection.joeyChat;

            // 定義client端的javascript function,供server端hub,透過dynamic的方式,呼叫所有Clients的javascript function
            chat.addMessage = function (message) {
                //當server端調用addMessage時,將server push的message資料,呈現在wholeMessage中
                $('#wholeMessages').append('<li>' + message + '</li>');
            };

            $("#send").click(function () {
                //呼叫server端的Hub物件,將#message資料傳給server
                chat.sendMessage($('#message').val());
                $('#message').val("");
            });

            //把connection打開
            $.connection.hub.start();
        });
    </script>
  1. 先引用 jQuery 與 signalR 的 js 檔。
  2. 很重要的一個步驟:加入一個 js 參考,其路徑為「根目錄/signalr/hubs」。 SignalR 會建立相關的 JavaScript,放置於此。
  3. 透過 $.connection.『server 端的 HubName』,即可建立對應該 hub 的 proxy object。要注意,首字母需小寫。
  4. 定義 client 端上,供 server 端通知的 JavaScript function,這邊的範例是 addMessage。
  5. 當按下送出按鈕時,呼叫 server 端的 SendMessage() 方法,只需要直接透過 proxy object 即可。要注意,首字母需小寫。
  6. 記得透過 $.connection.hub.start() ,把 connection 打開。

 

畫面

我們透過多個 browser 頁面,來模擬是否所有 client 都會收到同步的訊息。

image

接著在某一頁上輸入 hello world,按下送出的同時,所有頁面都會即時更新訊息。

image

 

結論

  1. 安裝相當簡單
  2. 使用相當簡單
  3. 應用面相當廣泛

其實我也只是初學者,但實在覺得這樣的東西實在把底層複雜的機制包裝的太美好了,忍不住趕緊跟大家介紹這個好物,相信很快就可以看到不同的應用或更深入的介紹了。

 

Sample

download : SignalR_WebSite.zip

對敏捷開發有興趣的朋友,可以參考我的粉絲專頁:91敏捷開發之路

對 TDD 課程有興趣的朋友,課程內容、大綱與學員心得,可以參考 skilltree 的公開課程:自動測試與 TDD 實務開發

若需要聯絡我,可以透過粉絲專頁私訊或是側欄的關於我。