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权限管理系统一期