ABP module-zero +AdminLTE+Bootstrap Table+jQuery權限管理系統第十六節--SignalR與ABP框架Abp.Web.SignalR及擴展


SignalR簡介

SignalR是什么?

ASP.NET SignalR 是為 ASP.NET 開發人員提供的一個庫,可以簡化開發人員將實時 Web 功能添加到應用程序的過程。實時 Web 功能是指這樣一種功能:當所連接的客戶端變得可用時服務器代碼可以立即向其推送內容,而不是讓服務器等待客戶端請求新的數據。

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。

SignalR內部有兩類對象:
Http持久連接(Persisten Connection)對象:

  • Connection表示用於發送單收件人,分組或廣播消息的簡單終端。持久連接API(由PersistentConnection類的.NET代碼表示)為開發人員提供了對SignalR公開的低級通信協議的直接訪問。用來解決長時間連接的功能。還可以由客戶端主動向服務器要求數據,而服務器端不需要實現太多細節,只需要處理PersistentConnection 內所提供的五個事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。

  • Hub(集線器)對象:基於連接API構建的更高級別的管道,允許您的客戶端和服務器直接調用彼此的方法。SignalR像魔術一樣處理跨機器邊界的調度,允許客戶端像本地方法一樣方便地調用服務器上的方法,反之亦然。對於使用遠程調用API(如.NET Remoting)的開發人員來說,使用Hubs通信模型將會很熟悉。使用集線器還允許您將強類型參數傳遞給方法,從而啟用模型綁定。

SignalR將整個信息的交換封裝起來,客戶端和服務器都是使用JSON來溝通的,在服務端聲明的所有Hub信息,都會生成JavaScript輸出到客戶端,.NET則依賴Proxy來生成代理對象,而Proxy的內部則是將JSON轉換成對象。

參考

官網及學習文檔:https://www.asp.net/signalr
github:https://github.com/SignalR
SignalR 參考項目:https://github.com/SignalR/Samples

實戰

工具要求:

  • Visual Studio 2013 及以上
  • .NET 4.5及以上
  • MVC 5及以上
  • SignalR版本2及以上
  1. 使用Visual Studio 2013,創建一個MVC項目

  2. 通過Nuget安裝SignalR包。
    install-package Microsoft.AspNet.SignalR

  3. 安裝SignalR成功后,SignalR庫的腳本將被添加進Scripts文件夾下。具體如下圖所示:
    image.png

  4. 在解決方案資源管理器中,右鍵單擊該項目(也可以新建一個類庫),選擇添加 新建文件夾,並添加一個名為Hubs的新文件夾。
    用鼠標右鍵單擊該Hubs文件夾,新建一個SignalR Hub Class(v2)類,並創建一個名為Chat .cs。您將使用此類作為將消息發送到所有客戶端的SignalR服務器中心。
    image.png

  5. 用下面的代碼替換Chat 類中的代碼。

    public class Chat : Hub
    {
        public void Send(string message)
        {
            Clients.All.send(message);
        }
    }
  1. 創建一個Startup類,如果開始創建MVC項目的時候沒有更改身份驗證的話,這個類會默認添加的,如果已有就不需要重復添加了。按照如下代碼更新Startup類。
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();
        }
    }
}
  1. 編輯HomeController在Controllers / HomeController.cs中找到的類,並將以下方法添加到類中。此方法返回您將在稍后的步驟中創建的聊天視圖。
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();
        }
    }
}

  1. 用以下代碼替換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>
    }

效果
image.png

SignalR聊天應用程序演示了兩個基本的SignalR開發任務:創建一個集線器作為服務器上的主要協調對象,並使用SignalR jQuery庫來發送和接收消息。

在代碼示例中,ChatHub類從Microsoft.AspNet.SignalR.Hub類派生。從Hub類派生是構建SignalR應用程序的有效方法。您可以在Hub類上創建公共方法,然后通過從網頁中的腳本調用這些方法來訪問這些方法。

在聊天代碼中,客戶端調用ChatHub.Send方法發送一條新消息。集線器通過調用Clients.All.addNewMessageToPage將消息發送給所有客戶端。
所述發送方法演示幾個集線器概念:

  • 在集線器上聲明公用方法,以便客戶端可以調用它們。
  • 使用Microsoft.AspNet.SignalR.Hub.Clients屬性訪問連接到此集線器的所有客戶端。
  • 調用客戶端上的函數(如addNewMessageToPage函數)來更新客戶端。
    SignalR和jQuery

代碼示例中的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創建的項目中,有一個很容易的方式使用 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 中實現了一些內置功能。

1. 通知

Abp.Web.SignalR 實現了 IRealTimeNotifier 接口來發送實時時間到客戶端。因此,你的用戶可以獲得實時的推送通知。

2. 在線客戶端

ABP提供了 IOnlineClientManager 來取得在線用戶的信息(如:注入IOnlineClientManager以及使用GetByUserIdOrNull, GetAllClients, IsOnline 方法)。為了能夠正常工作,IOnlineClientManager需要一個通信基礎設施。Abp.Web.SignalR 提供了這個基礎設施。如果安裝了SignalR,那么在應用的任何層都可以注入並使用IOnlineClientManager。

3. PascalCase vs. camelCase

Abp.Web.SignalR 使用 CamelCasePropertyNamesContractResolver 重寫了 SignalR's 默認的序列化類 ContractResolver。因此,在服務器端類具有 PascalCase 屬性,而在客戶端為了發送/接受對象,我們使用 camelCase (因為camelCase在JavaScript中更受歡迎)。如果你想在某些程序集中忽略這個,那么你可以將那些程序集添加AbpSignalRContractResolver.IgnoredAssemblies 列表中。

你的SignaR代碼

使用 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 接口。當然你可以根據你的需求,注冊它為單例模式。我們也使用屬性注入了SessionLogger

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權限管理系統一期


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM