SignalR 是一個集成的客戶端與服務器庫,基於瀏覽器的客戶端和基於 ASP.NET 的服務器組件可以借助它來進行雙向多步對話。 換句話說,該對話可不受限制地進行單個無狀態請求/響應數據交換;它將繼續,直到明確關閉。 對話通過永久連接進行,允許客戶端向服務器發送多個消息,並允許服務器做出相應答復,值得注意的是,還允許服務器向客戶端發送異步消息。它和AJax類 似,都是基於現有的技術。本身是一個復合體。一般情況下,SignalR會使用Javascript的長輪詢( long polling),實現客戶端和服務端通信。在WebSockets出現以后,SignalR也支持WebSockets通信。當然SignalR也使用 了服務端的任務並行處理技術以提高服務器的擴展性。它的目標整個 .NET Framework 平台,它也不限 Hosting 的應用程序,而且還是跨平台的開源項目。
SignalR 內的客戶端庫 (.NET/JavaScript) 提供了自動管理的能力,開發人員只需要直接使用 SignalR 的 Client Library 即可,同時它的 JavaScript 庫可和 jQuery 完美整合,因此能直接與像 jQuery 或 Knockout.js 一起使用。
SignalR內部有兩類對象:
· Persistent Connection:持久性連接,用來解決長時間連接的能力,而且還可以由客戶端主動向服務器要求數據,而服務器端也不需要實現太多細節,只需要處理 PersistentConnection 內所提供的五個事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
· Hub:信息交換器,用來解決 realtime 信息交換的功能,服務器端可以利用 URL 來注冊一個或多個 Hub,只要連接到這個 Hub,就能與所有的客戶端共享發送到服務器上的信息,同時服務器端可以調用客戶端的腳本,不過它背后還是不離 HTTP 的標准,所以它看起來神奇,但它並沒有那么神奇,只是 JavaScript 更強,強到可以用像 eval() 或是動態解釋執行的方式,允許 JavaScript 能夠動態的加載與執行方法調用而己。
SignalR 將整個交換信息的行為封裝得非常漂亮,客戶端和服務器全部都使用 JSON 來溝通,在服務器端聲明的所有 hub 的信息,都會一般生成 JavaScript 輸出到客戶端,.NET 則是依賴 Proxy 來生成代理對象,這點就和 WCF/.NET Remoting 十分類似,而 Proxy 的內部則是將 JSON 轉換成對象,以讓客戶端可以看到對象。
接下來Walkthrough一下:
1.新建一個empty web application
2.如果你裝VS2010和powershell2.0后,在package manager console下輸入:Install-Package SignalR后,會自動幫你下載和添加引用到您的項目
3.添加一個類作為Hub
public class MyChat : Hub { /// <summary> /// Sends the specified message. /// </summary> /// <param name="message">The message.</param> public void Send(string message) { // Call the addMessage method on all clients Clients.addMessage(message); } }
4.然后添加一個htm文件
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>dev home</title> </head> <body> <script src="../Scripts/jquery-1.7.2.js"></script> <script src="../Scripts/jquery.signalR-0.5.2.js"></script> <script src="/signalr/hubs" type="text/javascript"></script> <div> <script type="text/javascript"> var chat; $(function () { // Created proxy chat = $.connection.myChat; // Assign a function to be called by the server chat.addMessage = onAddMessage; // Register a function with the button click $("#broadcast").click(onBroadcast); // Start the connection $.connection.hub.start(); }); function onAddMessage(message) { // Add the message to the list $('#messages').append('<li>' + message + '</li>'); } function onBroadcast() { // Call the chat method on the server chat.send($('#message').val()); } </script> <input type="text" id="message" /> <input type="button" id="broadcast" value="send" /> <ul id="messages"> </ul> </div> </body> </html>
你會發現<script src="/signalr/hubs" type="text/javascript"></script>並沒有這個資源,別急,SingalR 會自動生成一個siganlr/hub 的橋接js。
然后你打開多個瀏覽器,你在一個瀏覽器中發送的消息,會同時在多個瀏覽器上出現。
我們可以看一下整個流程:
#broadcast 按鈕按下后 ---->觸發chat.send,這里的chat其實就是個代理,它調用了server端的Send方法---->Clients.addMessage(message);這里的Clients是dynamic類型的---->觸發所有chat.addMessage對應的handler--onAddMessage,然后所有的客戶端都能接受到廣播消息。
這里要注意的是客戶端和服務器段生成代理的規則,客戶端首字母都需要小寫,而且客戶端addMessage和send都與服務器段一一對應。而且這兩個方法名字不能相同。
public class Chat : Hub { public void SendMessage(string message) { Clients.sendMessage(message); } }
這樣的話就會出問題。
接下去會深入研究並且繼續寫一些日志,請大家關注和多提意見,謝謝。
參考:
http://www.cnblogs.com/wintersun/archive/2012/07/19/2599020.html
http://www.cnblogs.com/shanyou/archive/2012/07/28/2613693.html