SignalR是什麼?javascript
ASP.NET SignalR 是爲 ASP.NET 開發人員提供的一個庫,能夠簡化開發人員將實時 Web 功能添加到應用程序的過程。實時 Web 功能是指這樣一種功能:當所鏈接的客戶端變得可用時服務器代碼能夠當即向其推送內容,而不是讓服務器等待客戶端請求新的數據。html
ASP.NET SignalR是ASP.NET開發人員的一個新庫,可使開發實時Web功能變得簡單。SignalR容許服務器和客戶端之間的雙向通訊。服務器如今能夠將內容即時推送到鏈接的客戶端。SignalR包含用於鏈接管理(例如鏈接和斷開事件),鏈接分組和受權的API。通常狀況下,SignalR會使用JavaScript(Ajax長時間輪詢)的長輪詢(long polling)的方式來實現客戶端和服務器通訊,隨着Html5中WebSockets出現,SignalR也支持WebSockets通訊和支持CORS(跨源資源共享)。另外SignalR開發的程序不只僅限制於宿主在IIS中,也能夠宿主在任何應用程序,包括控制檯,客戶端程序和Windows服務等,另外還支持Mono,這意味着它能夠實現跨平臺部署在Linux環境下。JSONP沒有配置,而且鏈接不是跨域的,若是客戶端和服務器都支持,則使用WebSocket。java
SignalR內部有兩類對象:
Http持久鏈接(Persisten Connection)對象:jquery
Connection表示用於發送單收件人,分組或廣播消息的簡單終端。持久鏈接API(由PersistentConnection類的.NET代碼表示)爲開發人員提供了對SignalR公開的低級通訊協議的直接訪問。用來解決長時間鏈接的功能。還能夠由客戶端主動向服務器要求數據,而服務器端不須要實現太多細節,只須要處理PersistentConnection 內所提供的五個事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 便可。git
Hub(集線器)對象:基於鏈接API構建的更高級別的管道,容許您的客戶端和服務器直接調用彼此的方法。SignalR像魔術同樣處理跨機器邊界的調度,容許客戶端像本地方法同樣方便地調用服務器上的方法,反之亦然。對於使用遠程調用API(如.NET Remoting)的開發人員來講,使用Hubs通訊模型將會很熟悉。使用集線器還容許您將強類型參數傳遞給方法,從而啓用模型綁定。github
SignalR將整個信息的交換封裝起來,客戶端和服務器都是使用JSON來溝通的,在服務端聲明的全部Hub信息,都會生成JavaScript輸出到客戶端,.NET則依賴Proxy來生成代理對象,而Proxy的內部則是將JSON轉換成對象。跨域
官網及學習文檔:https://www.asp.net/signalr
github:https://github.com/SignalR
SignalR 參考項目:https://github.com/SignalR/Samples瀏覽器
工具要求:服務器
install-package Microsoft.AspNet.SignalR
安裝SignalR成功後,SignalR庫的腳本將被添加進Scripts文件夾下。具體以下圖所示:
app
在解決方案資源管理器中,右鍵單擊該項目(也能夠新建一個類庫),選擇添加 新建文件夾,並添加一個名爲Hubs的新文件夾。
用鼠標右鍵單擊該Hubs文件夾,新建一個SignalR Hub Class(v2)類,並建立一個名爲Chat .cs。您將使用此類做爲將消息發送到全部客戶端的SignalR服務器中心。
public class Chat : Hub { public void Send(string message) { Clients.All.send(message); } }
using Owin; using Microsoft.Owin; [assembly: OwinStartup(typeof(SignalRChat.Startup))] namespace SignalRChat { public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here app.MapSignalR(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace BasicChat.Mvc.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; return View(); } public ActionResult About() { ViewBag.Message = "Your app description page."; return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } } }
用如下代碼替換Chat.cshtml的內容。
將SignalR和其餘腳本庫添加到Visual Studio項目中時,程序包管理器可能會安裝比本主題中顯示的版本更新的SignalR腳本文件版本。確保代碼中的腳本引用與項目中安裝的腳本庫的版本相匹配。
@{ ViewBag.Title = "聊天窗口"; } <h2>Chat</h2> <div class="container"> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="discussion"></ul> </div> @section scripts { <!--引用SignalR庫. --> <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script> <!--引用自動生成的SignalR 集線器(Hub)腳本.在運行的時候在瀏覽器的Source下可看到 --> <script src="~/signalr/hubs"></script> <script> $(function () { // 引用自動生成的集線器代理 var chat = $.connection.serverHub; // 定義服務器端調用的客戶端sendMessage來顯示新消息 chat.client.sendMessage = function (name, message) { // 向頁面添加消息 $('#discussion').append('<li><strong>' + htmlEncode(name) + '</strong>: ' + htmlEncode(message) + '</li>'); }; // 設置焦點到輸入框 $('#message').focus(); // 開始鏈接服務器 $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // 調用服務器端集線器的Send方法 chat.server.send($('#message').val()); // 清空輸入框信息並獲取焦點 $('#message').val('').focus(); }); }); }); // 爲顯示的消息進行Html編碼 function htmlEncode(value) { var encodedValue = $('<div />').text(value).html(); return encodedValue; } </script> }
效果
SignalR聊天應用程序演示了兩個基本的SignalR開發任務:建立一個集線器做爲服務器上的主要協調對象,並使用SignalR jQuery庫來發送和接收消息。
在代碼示例中,ChatHub類從Microsoft.AspNet.SignalR.Hub類派生。從Hub類派生是構建SignalR應用程序的有效方法。您能夠在Hub類上建立公共方法,而後經過從網頁中的腳本調用這些方法來訪問這些方法。
在聊天代碼中,客戶端調用ChatHub.Send方法發送一條新消息。集線器經過調用Clients.All.addNewMessageToPage將消息發送給全部客戶端。
所述發送方法演示幾個集線器概念:
代碼示例中的Chat.cshtml視圖文件顯示瞭如何使用SignalR jQuery庫與SignalR集線器進行通訊。代碼中的基本任務是建立對集線器的自動生成代理的引用,聲明服務器能夠調用的將內容推送到客戶端的功能,以及啓動鏈接以將消息發送到集線器。
如下代碼顯示瞭如何在腳本中建立回調函數。服務器上的集線器類調用此函數將內容更新推送到每一個客戶端。對htmlEncode函數的可選調用顯示了一種在將消息內容顯示在頁面以前對其進行HTML編碼的方法,以防止腳本注入。
chat.client.addNewMessageToPage = function (name, message) { // Add the message to the page. $('#discussion').append('<li><strong>' + htmlEncode(name) + '</strong>: ' + htmlEncode(message) + '</li>'); };
如下代碼顯示如何打開與集線器的鏈接。代碼啓動鏈接,而後傳遞一個函數來處理「聊天」頁面中「 發送」按鈕上的點擊事件。
這種方法能夠確保在事件處理程序執行以前創建鏈接。
$.connection.hub.start().done(function () { $('#sendmessage').click(function () { // Call the Send method on the hub. chat.server.send($('#displayname').val(), $('#message').val()); // Clear text box and reset focus for next comment. $('#message').val('').focus(); }); });
按照B/S模式來看,運行程序的時候,Web頁面就與SignalR的服務創建了鏈接,具體的創建鏈接的代碼就是:\(.connection.hub.start()。這句代碼的做用就是與SignalR服務創建鏈接,後面的done函數代表創建鏈接成功後爲發送按鈕註冊了一個click事件,當客戶端輸入內容點擊發送按鈕後,該Click事件將會觸發,觸發執行的操做爲: chat.server.send(\)('#message').val())。這句代碼表示調用服務端的send函數,而服務端的Send韓式又是調用全部客戶端的sendMessage函數,而客戶端中sendMessage函數就是將信息添加到對應的消息列表中。這樣就實現了廣播消息的功能了。
在基於ABP建立的項目中,有一個很容易的方式使用 SignalR,那就是使用Abp.Web.SignalR。詳情請參考SignalR文檔。
使用Nuget安裝[Abp.Web.SignalR(http://www.nuget.org/packages/Abp.Web.SignalR)到你的項目中(一般是你的Web項目)而且在模塊中添加被依賴的模塊:
[DependsOn(typeof(AbpWebSignalRModule))] public class YourProjectWebModule : AbpModule { //... }
而後,在你的OWIN Startup類中使用 MapSignalR 方法,正如你往常那樣作的:
[assembly: OwinStartup(typeof(Startup))] namespace MyProject.Web { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); //... } } }
注意:Abp.Web.SignalR 依賴於
Microsoft.AspNet.SignalR.Core。因此,你須要安裝 Microsoft.AspNet.SignalR到你的Web項目中。詳情請參考SignalR文檔。
腳本 abp.signalr.js 應該被引用到頁面中。它位於 Abp.Web.Resources 包中(它已經被安裝到啓動模板中)。 咱們應該在signalr hubs 後引用它:
<script src="~/signalr/hubs"></script> <script src="~/Abp/Framework/scripts/libs/abp.signalr.js"></script>
這麼作了之後,SignalR就已經恰當的配置和集成到你的項目中了。
###創建鏈接
當 abp.signalr.js 被引用到頁面後,ABP會自動的鏈接到你的服務器。通常咱們都會這麼作,可是在某些狀況下你不想這樣作。你能夠像下面代碼所示禁用自動鏈接:
<script> abp.signalr = abp.signalr || {}; abp.signalr.autoConnect = false; </script>
在這種狀況下,你能夠手動調用 abp.signalr.connect() 函數來鏈接服務器。
當客戶端鏈接到服務器時,全局事件 "abp.signalr.connected" 會被觸發。當鏈接創建成功的時候,你能夠註冊這個事件來採起相應的行動。詳情請參考Javascript函數庫
你能夠在應用程序中使用全部的SignalR的功能。還有,在 Abp.Web.SignalR 中實現了一些內置功能。
Abp.Web.SignalR 實現了 IRealTimeNotifier 接口來發送實時時間到客戶端。所以,你的用戶能夠得到實時的推送通知。
ABP提供了 IOnlineClientManager 來取得在線用戶的信息(如:注入IOnlineClientManager以及使用GetByUserIdOrNull, GetAllClients, IsOnline 方法)。爲了可以正常工做,IOnlineClientManager須要一個通訊基礎設施。Abp.Web.SignalR 提供了這個基礎設施。若是安裝了SignalR,那麼在應用的任何層均可以注入並使用IOnlineClientManager。
Abp.Web.SignalR 使用 CamelCasePropertyNamesContractResolver 重寫了 SignalR's 默認的序列化類 ContractResolver。所以,在服務器端類具備 PascalCase 屬性,而在客戶端爲了發送/接受對象,咱們使用 camelCase (由於camelCase在JavaScript中更受歡迎)。若是你想在某些程序集中忽略這個,那麼你能夠將那些程序集添加AbpSignalRContractResolver.IgnoredAssemblies 列表中。
使用 Abp.Web.SignalR 包也會簡化你的 SignalR代碼。假設咱們想要添加一個Hub到你的應用程序中:
public class MyChatHub : Hub, ITransientDependency { public IAbpSession AbpSession { get; set; } public ILogger Logger { get; set; } public MyChatHub() { AbpSession = NullAbpSession.Instance; Logger = NullLogger.Instance; } public void SendMessage(string message) { Clients.All.getMessage(string.Format("User {0}: {1}", AbpSession.UserId, message)); } public async override Task OnConnected() { await base.OnConnected(); Logger.Debug("A client connected to MyChatHub: " + Context.ConnectionId); } public async override Task OnDisconnected(bool stopCalled) { await base.OnDisconnected(stopCalled); Logger.Debug("A client disconnected from MyChatHub: " + Context.ConnectionId); } }
爲了使咱們的Hub能夠簡單的註冊到依賴注入系統中,咱們能夠實現 ITransientDependency 接口。固然你能夠根據你的需求,註冊它爲單例模式。咱們也使用屬性注入了Session和Logger。
SendMessage是hub的一個方法,它能夠被客戶端使用。在這個方法中,咱們能夠調用全部客戶端的 getMessage函數。正如你看到的那樣,咱們可使用AbpSession來得到當前的用戶id(若是用戶已經登陸)。爲了演示,咱們也重寫了 OnConnected 和 OnDisconnected,實際這裏是不須要的。
下面是用在Hub中,用來發送/接受信息的客戶端腳本:
var chatHub = $.connection.myChatHub; //get a reference to the hub chatHub.client.getMessage = function (message) { //register for incoming messages console.log('received message: ' + message); }; abp.event.on('abp.signalr.connected', function() { //register for connect event chatHub.server.sendMessage("Hi everybody, I'm connected to the chat!"); //send a message to the server });
而後,在咱們須要發送信息到服務器時,咱們就可使用 chatHub。詳情請參考SignalR文檔。
Github項目地址:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS
本文連接:http://www.cnblogs.com/anyushengcms/p/8035924.html
ABP+AdminLTE+Bootstrap Table權限管理系統一期
Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS
返回總目錄:ABP+AdminLTE+Bootstrap Table權限管理系統一期