推薦這個blog:

Award


(ASP.NET 2010~2014年)

協作出版作品

其他資源

簡體中文blog

最新回應

前言

一早起床後,在消化 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


關連文章

[Tip]如何在 web developer tool 的 console 中,使用 jQuery 語法

[.NET]透過 T4 產生對應 DB table 的 entity

[.NET][BDD][TDD]BDD with SpecFlow by MS Test (1) – BDD與TDD範例

[.NET][Tool]靜態程式碼分析工具簡介

回應

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 流浪小風

    有點像是JavaScript版的Wcf Duplex Service啊, 改用JavaScript來實現Client端 :P

    2012/7/1 下午 03:52 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by KKBruce

    我還沒細看 SignalR 內容,不過在 HTML5 中有個 Server Side 技術,可以完成一模一樣的功能,純 JavaScript Code。

    我自己是這樣想:

    Server Side 技術:需 Browsers' 支援 HTML5 ( IE 10 以下應該都先自盡 XD )

    SignalR 技術:由 Server 端實作,沒有 Clinet 端 Browser Version 問題。

    2012/7/1 下午 04:05 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 小桶子

    Html5 的socket 需要實作訊息交握~~比較麻煩~~~這個幾乎全簡化了= =

    2012/7/1 下午 09:28 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by programlin

    看起來應該是封裝長輪詢的做法,但簡化了Server端長輪詢的複雜度.
    目前長輪詢的最大缺點在於當太多的Client產生時,Server的Loading會加重許多.
    不過目前HTML也沒有其他比較好的方案,真是個不錯的東西,

    HTML5的Web Socket到目前為止還未定案,更不要說Support的Browser支援問題,不過Web Socket畢竟是未來的Web主流,很多東西都必須基於此基礎才能達成,相信未來一定會有很多的Library可用.

     

    2012/7/2 上午 11:00 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 網頁設計

    感謝版主的分享!!!!

    了解許多!!!

    2012/7/2 下午 05:06 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 火凤燎原

    to KKBruce : 我试过了,不支持IE6 IE7

    其它的IE8-IE10是支持的,FIREFOX,GOOGLE CHROM都是支持的~苹果的没试过~
     

    2012/7/5 下午 02:13 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by step

    类似java的dwr

    2012/7/5 下午 04:04 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 當麻許

    感謝91哥分享

    2012/7/9 下午 05:54 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by remhom

    好東西!很棒的分享 :)

    2012/7/11 上午 11:19 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by amu

    請問一下, 假設虛擬目錄名稱是 test

    是要在test資料夾下建立 signalr/hubs 的目錄嗎?

    目前似乎跑不起來@ @

     

     

    2012/7/12 下午 05:09 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 91

    to amu :

     signalr/hubs是吃「站台根目錄」唷。

     

    2012/7/12 下午 06:13 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by amu

    to 91 : 請問還有甚麼要注意的地方嗎,似乎還是不行.

    但如果是跑在虛擬伺服器上卻可以@ @?

    此時在瀏覽器上網址列鍵入 http://localhost:xxxxx/SignalR_WebSite/signalr/hubs 會打開一個由SignalR所產生的 js 檔,

    所以hubs是要先放一個空白檔案嗎? 有點搞不太懂@ @
     

    2012/7/12 下午 10:47 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 91

    to amu : 你的虛擬伺服器跟iis,應該是相差一個站台或目錄名稱。

    你完全不需要新增signalr/hubs的資料夾,那是SignalR會自己幫你產生js檔到那底下。

    正常來說,src只要設定為src="/signalr/hubs"就可以了。

    你也可以用developer tool, 在瀏覽器上按F12,去console的tab中,看有沒有request這一支動態產生的js檔,造成失敗的情況。
     

    2012/7/12 下午 11:48 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 91

    to amu :
    請參考當麻的介紹,應該就是您碰到的問題。

    http://www.dotblogs.com.tw/junegoat/archive/2012/07/16/signalr-hubs-web-config-settings.aspx

    web.config 上要加上一段,讓 iis 不會誤判成虛擬目錄。

    2012/7/17 上午 12:09 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by Jed

    好久沒來看,一上來就看到你這篇文章

    可惜我們家已經先用其他方式implement了,不然這技術的確是好物啊

    2012/7/17 下午 05:08 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 91

    to Jed :

    Jed董你揪久沒來啊...

    什麼時候在一起喝個咖啡吧,真是有點想念你啊...
     

    2012/7/17 下午 05:13 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by Jed

    to 91 :
    對啊,好久沒跟你們學習了,上點部落都好心虛XD
     

    2012/7/18 下午 07:25 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 91

    to Jed :

    有小公主了咩,等我有小朋友,我應該也會荒廢一陣子 XD
     

    2012/7/18 下午 07:30 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by Leo

    91 大:今天試玩,發現要改用以下完整命名空間的方式才能取得 Sample,不知道是不是我的環境問題,還是提供您參考:

    Install-Package Microsoft.AspNet.SignalR.Sample

     

    2013/4/22 下午 12:25 | 回覆

  • # re: [.NET]SignalR簡介 - 建立 realtime 的網站 by 一個蛋

    91大,

        使用IE開啟時,下方狀態列會有"正在等候xxxxxxx"的訊息,有可能不顯示嗎?

        還是因為Socket的關係,必須保持連線而出現此訊息呢?

    2013/8/13 下午 06:34 | 回覆

登入後使用進階評論

Please add 1 and 4 and type the answer here: