1. 程式人生 > >ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統第十六節--SignalR與ABP框架Abp.Web.SignalR及擴充套件

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轉換成物件。

參考

實戰

工具要求:

  • 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文件

相關推薦

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--QuartzABP框架Abp.Quartz擴充套件

Quartz簡介 Quartz.NET是一個開源的作業排程框架,是 OpenSymphony 的 Quartz API 的.NET移植,它用C#寫成,可用於winform和asp.net應用中。它提供了巨大的靈活性而不犧牲簡單性。你能夠用它來為執行一個作業而建立簡單的或複雜的排程。它有很多特徵,如:資料庫支

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--SignalRABP框架Abp.Web.SignalR擴充套件

SignalR簡介 SignalR是什麼? ASP.NET SignalR 是為 ASP.NET 開發人員提供的一個庫,可以簡化開發人員將實時 Web 功能新增到應用程式的過程。實時 Web 功能是指這樣一種功能:當所連線的客戶端變得可用時伺服器程式碼可以立即向其推送內容,而不是讓伺服器等待客戶端請求新的資

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--後臺工作者HangFireABP框架Abp.Hangfire擴充套件

HangFire與Quartz.NET相比主要是HangFire的內建提供整合化的控制檯,方便後臺檢視及監控,對於大家來說,比較方便。 HangFire是什麼 Hangfire是一個開源框架(.NET任務排程框架),可以幫助您建立,處理和管理您的後臺作業,處理你不希望放入請求處理管道的操作: 通知/通訊;

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--小結,Bootstrap Table之角色管理以及module-zero角色管理

寫在前面的話           很多人說ABP不適合高併發大型,有一定的道理,但是我覺得還是可以的,就看架構師的能力了,我之前公司就是ABP絕對百萬資料級專案,是一個線上教育網站,涉及到平臺,學院,院系,班級,課程,學生等,一個平臺多少大學,一個大學多少院系,一個院系多少班級多少課程,其負責程度一

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統--快取小結ABP框架專案中 Redis Cache的實現

快取 為什麼要用快取 為什麼要用快取呢,說快取之前先說使用快取的優點。 減少寄宿伺服器的往返呼叫(round-trips)。 如果快取在客戶端或是代理,將減少對伺服器的請求,減少頻寬。 減少對資料庫伺服器的往返呼叫(round-trips)。 當內容快取在web伺服器,能夠減輕對資料庫的請求。 減少網路

ABP module-zero +AdminLTE+Bootstrap Table+jQuery許可權管理系統三節--RBAC模式ABP許可權管理(附贈福利)

角色訪問控制(RBAC) 角色訪問控制(RBAC)應該是目前用得最多也是關注最多的許可權管理模型了。 許可權(Permission)與角色(Role)相關聯,使用者(User)通過成為適當角色的成員而得到這些角色的許可權。這就極大地簡化了許可權的管理。 RBAC引入了角色(Role)概念,目的應該是解耦了P

ABP module-zero +AdminLTE+Bootstrap Table+jQuery權限管理系統--小結,Bootstrap Table之角色管理

增刪 習慣 etc 根據 很好 這不 update 必須 virtual 返回總目錄:ABP+AdminLTE+Bootstrap Table權限管理系統一期 很多人說ABP不適合高並發大型,有一定的道理,但是我覺得還是可以的,就看架構師的能

ABP+AdminLTE+Bootstrap Table許可權管理系統--Bootstrap Table使用者管理列表以及Module Zero之使用者管理

   使用者實體       使用者實體代表應用的一個使用者,它派生自AbpUser類,如下所示: public class User : AbpUser<Tenant, User> { //add your own user properties here

ABP+AdminLTE+Bootstrap Table許可權管理系統--AdminLTE模板選單處理

 AdminLTE選單       上節我們把佈局頁,也有的臨時的選單,但是選單不是應該動態載入的麼?,所以我們這節來寫選單.首先我們看一下AdminLTE原始碼裡面的選單以及結構. <aside class="main-sidebar"> <!--

ABP+AdminLTE+Bootstrap Table許可權管理系統--AdminLTE引入模板頁和佈局和選單

 AdminLTE    首先去官網下載包下來,然後引入專案.   然後我們在web層新增區域Admin以及Common,關於AdminLTE的地址我們放在Common路勁下面.   在Common下新增LayoutController控制器. Layout 這裡選單我們先不管,在後

ABP+AdminLTE+Bootstrap Table許可權管理系統--倉儲,服務,服務介面依賴注入

AbpModule      在ABP框架中,倉儲,服務,這塊算是最為重要一塊之一了.ABP框架提供了建立和組裝模組的基礎,一個模組能夠依賴於另一個模組,一個程式集可看成一個模組, 一個模組可以通過一個類來定義這個模組,而給定義這個類要繼承自已經瘋轉好的AbpModule..net通過反射來獲取這些程

ABP+AdminLTE+Bootstrap Table許可權管理系統--登入邏輯幾種abp封裝的Javascript函式庫

        簡介        經過前幾節,我們已經解決資料庫,模型,DTO,控制器和注入等問題.那麼再來看一下登入邏輯.這裡算是前面幾節的一個初次試水. 首先我們資料庫已經有的相應的資料. 新增Login方法        模型和DTO已經建好,所以我們直接在服務層新增Login方法就可

ABP+AdminLTE+Bootstrap Table許可權管理系統三節--abp分層體系,實體相關ABP模組系統

ABP模組系統  說了這麼久,還沒有詳細說到abp框架,abp其實基於DDD(領域驅動設計)原則的細看分層如下: 再看我們專案解決方案如下: JCmsErp.Application,應用層:進行展現層與領域層之間的協調,協調業務物件來執行特定的應用程式的任務。它不包含業務邏輯,主要包

ABP+AdminLTE+Bootstrap Table許可權管理系統八節--ABP錯誤機制AbpSession相關

((ClaimsPrincipal)Thread.CurrentPrincipal).Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);        需要獲取會話資訊則必須實現IAbpSession介面。雖然你

ABP+AdminLTE+Bootstrap Table許可權管理系統--abp控制器擴充套件json封裝

 一,控制器AbpController    說完了Swagger ui 我們再來說一下abp對控制器的處理和json的封裝.    首先我們定義一個控制器,在新增控制器的時候,控制器會自動繼承自AbpController,AbpController

abp(net core)+easyui+efcore實現倉儲管理系統——選單 ()

系統目錄 abp(net core)+easyui+efcore實現倉儲管理系統——ABP總體介紹(一) abp(net core)+easyui+efcore實現倉儲管理系統——解決方案介紹(二) abp(net core)+easyui+efcore實

ABP+AdminLTE+Bootstrap Table許可權管理系統第一--使用ASP.NET Boilerplate模板建立解決方案

ABP+AdminLTE+Bootstrap Table許可權管理系統一期 Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS 前往部落格園總目錄

ABP+AdminLTE+Bootstrap Table許可權管理系統一期

 初衷    學而時習之,不亦說乎,溫顧溫知新,可以為師矣.           看懂遠不如動手去做,動手做才能發現很多自己不懂的問題,不斷的反思和總結,“樂於分享是一種境界的突破”。" 分享是很有意思,也是可以鍛鍊人的。 分享意味著自我的不斷淨化提升,不給自己後退的餘地。為什麼這麼說呢?因為:一,分

ABP+AdminLTE+Bootstrap Table許可權管理系統第二--在ABP的基礎做資料庫指令碼處理

      第一點,上一篇文章中我們講到codefirst中一些問題包括如圖,codefirst在每次執行命令的時候會生成新的類,後來會越來越多。 1,codefirst在執行的資料庫遷移過程中產生了很多檔案,對於強迫症的我而言特別不爽,這些其實是可以不用生成的。 2,在codefirst實際

[ABP開源專案]--vue+vuex+vue-router+EF的許可權管理系統

好久沒寫文字了,當然大家也不期待嘛,反正看程式碼就行了。 演示網站 首先說下這個專案吧。 如標題一樣是基於VUE+.NET開發的框架,也是群友一直吼吼吼要一個vue版本的ABP框架。 我們先來看看首頁吧: 還比較酷炫,提供下演示賬號 演示地址:http://vue.yo