先前限量提到了WebSocket這個HTML5標準的網頁即時傳輸技術,如果是用.Net的開發者有福了,因為Microsoft為了ASP.Net也能簡單使用即時傳輸技術,開啟了SignalR Project。
簡單來說,SignalR是個提供開發人員能夠輕鬆使用更Hight Level API網頁即時傳輸技術的Library,SignalR將過去與現在實作即時傳輸的方法整合在一起,根據不同狀況選擇適合的方法,WebSocket就是其中之一,且WebSocket為SignalR預設選擇的方法。像大部分的情況下,大家都會想使用WebSocket,畢竟這是目前最佳的解決方法,但要使用WebSocket不僅Client瀏覽器要支援WebSocket之外,Server也限制只能在IIS 8以上才有支援(IIS部屬WebSocket服務)。這時候如果使用Signal來實作的話就可以不用花時間考慮這麻煩的問題,因為SignalR會自動選擇用WebSocket或Long Polling的方法,下圖為SignalR選擇傳輸方式的流程圖。
簡單來說,SignalR是個提供開發人員能夠輕鬆使用更Hight Level API網頁即時傳輸技術的Library,SignalR將過去與現在實作即時傳輸的方法整合在一起,根據不同狀況選擇適合的方法,WebSocket就是其中之一,且WebSocket為SignalR預設選擇的方法。像大部分的情況下,大家都會想使用WebSocket,畢竟這是目前最佳的解決方法,但要使用WebSocket不僅Client瀏覽器要支援WebSocket之外,Server也限制只能在IIS 8以上才有支援(IIS部屬WebSocket服務)。這時候如果使用Signal來實作的話就可以不用花時間考慮這麻煩的問題,因為SignalR會自動選擇用WebSocket或Long Polling的方法,下圖為SignalR選擇傳輸方式的流程圖。
要使用SignalR很簡單,只要在你的Web專案裡有一個Hub的Class,並在Hub裡實作Server端要進行的操作即可,接著在Client端要有對應的JavaScript檔與Hub進行溝通,就輕鬆完成即時傳輸的網頁。下面限量將在MVC5專案中使用SignalR完成簡單的聊天室功能:
(1) 在NuGet裡搜尋SignalR並安裝(目前版本來到2.0)。
加入之後可以看到Script裡多了一些JS檔。
(1) 在NuGet裡搜尋SignalR並安裝(目前版本來到2.0)。
加入之後可以看到Script裡多了一些JS檔。
(2) 在專案裡增加一個OWIN Startup Class。(注意:如果在建立MVC5專案時如果有選擇一些設定時,MVC5會幫你建立一個Startup的Class,一個專案只有一個Startup Class,所以要注意看看專案裡是否本來就有存在了)。
(3) 將Startup.cs修改成以下程式碼(注意:如果專案本身就有Startup Class時,在安裝好SignalR時就會自動幫你加入[assembly: OwinStartup( typeof( WebSample.Startup ) )],所以只要在Configuration()裡加上app.MapSignalR()。還有另一點要注意的是,下面修改的程式碼是Signal 2.0的修改方式,不適用於2.0之前的版本)。
Startup.cs
(4) 在專案裡加入Hub Class,並撰寫Server端邏輯處理的方法(注意:由於安裝SignalR後不會建立額外的資料夾,所以SignarR相關的程式碼可根據自己的規劃放置)。
ChatHub.cs
在範例中,限量撰寫了兩個方法,Hello為當有遊客進入聊天室時,Server會取得該遊客的名字並通知其他遊客該遊客加入聊天;Echo為當遊客發送訊息出來時,Server會將訊息導至其他遊客的視窗中。
(5) 在View裡加入與Hub溝通的JavaScript Code。
Index.cshtml
在撰寫對應的JavaScript Code時,要將jquery.signalR-2.0.3.js拉進來,並引用~/signalr/hubs,你一定會覺得很奇怪,在Script資料夾裡根本沒有hubs這鬼檔案。沒錯,那就是個鬼檔案,因為這個js檔只會在執行的時候出現,是SignalR Library自動產生來與Hub作對應。
在JS Code裡面,首先要宣告一個Hub的對應物件才能進行雙向溝通的操作,使用$.connection.{Hub Class名稱}取得物件。接著在依序實作在Server中呼叫的對應JS方法,這些方法必須放在{Hub物件}.client的Namespace下。在對應ChatHub.cs與JS Code可以看到兩者之間的關係。
再來在$.connection.hub.start().done(function(){...})裡實作與Server連線啟動時要做的事,就和WebSocket的onopen()監聽事件一樣。
執行結果:
從執行結果可以看到和WebSocket一模一樣的效果,只要少許的程式碼也不用另外加一個WebSocket Server就能夠實現即時傳輸的網頁,真是太方便了。
(3) 將Startup.cs修改成以下程式碼(注意:如果專案本身就有Startup Class時,在安裝好SignalR時就會自動幫你加入[assembly: OwinStartup( typeof( WebSample.Startup ) )],所以只要在Configuration()裡加上app.MapSignalR()。還有另一點要注意的是,下面修改的程式碼是Signal 2.0的修改方式,不適用於2.0之前的版本)。
Startup.cs
using Microsoft.Owin; using Owin; [assembly: OwinStartup( typeof( WebSample.Startup ) )] namespace WebSample { public class Startup { public void Configuration( IAppBuilder app ) { app.MapSignalR(); } } }
(4) 在專案裡加入Hub Class,並撰寫Server端邏輯處理的方法(注意:由於安裝SignalR後不會建立額外的資料夾,所以SignarR相關的程式碼可根據自己的規劃放置)。
ChatHub.cs
using Microsoft.AspNet.SignalR; namespace WebSample { public class ChatHub : Hub { public void Echo( string name, string msg ) { Clients.All.sendMsgToOthers( name, msg ); } public void Hello(string name) { Clients.All.welcome(string.Format("{0} 加入聊天", name)); } } }
在範例中,限量撰寫了兩個方法,Hello為當有遊客進入聊天室時,Server會取得該遊客的名字並通知其他遊客該遊客加入聊天;Echo為當遊客發送訊息出來時,Server會將訊息導至其他遊客的視窗中。
(5) 在View裡加入與Hub溝通的JavaScript Code。
Index.cshtml
<h2>聊天室</h2> <div> <ul id="msg_list"></ul> </div> <div> @Html.TextBox( "msg", null, new { @class = "form-control", placeholder = "在此輸入訊息" } ) <input type="button" class="btn" value="送出" id="btn_send" /> @Html.Hidden("user_name") </div> @section scripts { <script src="~/Scripts/jquery.signalR-2.0.3.js"></script> <script src="~/signalr/hubs"></script> <script> $(function () { var chat = $.connection.chatHub; $('#user_name').val(prompt('輸入暱稱:', '')); chat.client.welcome = function (msg) { alert(msg); }; chat.client.sendMsgToOthers = function (name, msg) { $('#msg_list').append('<li>'+name+': '+msg+'</li>'); }; $.connection.hub.start().done(function () { chat.server.hello($('#user_name').val()); }); $('#btn_send').click(function () { chat.server.echo($('#user_name').val(), $('#msg').val()); }); }); </script> }
在撰寫對應的JavaScript Code時,要將jquery.signalR-2.0.3.js拉進來,並引用~/signalr/hubs,你一定會覺得很奇怪,在Script資料夾裡根本沒有hubs這鬼檔案。沒錯,那就是個鬼檔案,因為這個js檔只會在執行的時候出現,是SignalR Library自動產生來與Hub作對應。
在JS Code裡面,首先要宣告一個Hub的對應物件才能進行雙向溝通的操作,使用$.connection.{Hub Class名稱}取得物件。接著在依序實作在Server中呼叫的對應JS方法,這些方法必須放在{Hub物件}.client的Namespace下。在對應ChatHub.cs與JS Code可以看到兩者之間的關係。
再來在$.connection.hub.start().done(function(){...})裡實作與Server連線啟動時要做的事,就和WebSocket的onopen()監聽事件一樣。
執行結果:
從執行結果可以看到和WebSocket一模一樣的效果,只要少許的程式碼也不用另外加一個WebSocket Server就能夠實現即時傳輸的網頁,真是太方便了。
參考來源:
留言
張貼留言