Toggle navigation
首页
产品中心
全新RDIF.vNext低代码框架
镇店
.NET C/S开发框架
.NET Web敏捷开发框架
.NET 快速开发框架(全新EasyUI版本)
.NET 代码生成器
.NET WebAPI服务端开发框架
客户案例
付款方式
国思学堂
技术文章
新闻资讯
下载
关于
首页
技术文章
.NET(Core)
正文
原创
2019-08-21
浏览 (
14289
)
史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式
## 1、概述 ## 通过前两篇 [史上最全面的SignalR系列教程-1、认识SignalR](http://www.guosisoft.com/article/detail/225) [史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式](http://www.guosisoft.com/article/detail/226) [RDIFramework.NET敏捷开发框架通过SignalR技术整合即时通讯(IM)](http://www.guosisoft.com/article/detail/229) 文章对SignalR的介绍,我们对SignalR已经有了全面的认识。SignalR API 客户端和服务器端持久连接的通信方式,一次连接代表一个发送单个、分组或者广播消息的简单终端。持久连接的API(表现在.NET的PersistentConnection 类上)给了开发人员低价访问SignalR所暴露的通信协议的条件。使用这种连接方式,就像开发人员使用WCF一样。 本篇将继续在上一篇的基础上,讲解SignalR通过最常用的集线器方式实现消息推送与发送。 我们知道SignalR的通信模型主要是两类Persistent Connections与Hubs。Hub是一种更高级的管道,它在连接协议上允许客户端和服务器端能够直接调用彼此的方法。SignalR的这种自动分发跨机器边界调度的方法就像施了魔法一样,让客户端调用服务端的方法像调用本地一样简单,反之亦然。使用Hub的模式就像开发人员使用远程API一样,比如 .NET Remoting。使用Hub同样能够让你传递类型化的参数到方法上进行模型绑定。通过Hubs实现服务端消息推送到客户端,抽象结构图如下。 ![SignalR Hub 结构流程图](http://doc.rdiframework.net/blog/article/20190814085139780.png) ## 2、SignalR Hub 原理分析 ## SignalR具体是如何到达实行性的呢?SignalR 的实现机制与 .NET WCF 或 Remoting 是相似的,都是使用远程代理来实现。SignalR 将整个连接,信息交换过程封装得非常漂亮,客户端与服务器端全部使用 JSON 来交换数据。 当服务端的代码访问一个客户端的方法时,一个数据包被自动传输,数据包中包含了函数方法参数的名称(如果是一个对象,那么这个对象会被序列化成JSON)。客户端然后根据客户端的代码匹配方法的名称。如果找到相应的匹配方法,那么久调用相应的函数执行反序列化的参数。 ## 3、Hubs实现实时消息流程 ## - 在服务器端定义对应的hub class; - 在客户端定义hub class 所对应的 proxy 类; - 在客户端与服务器端建立连接(connection); - 然后客户端就可以调用 proxy 对象的方法来调用服务器端的方法,也就是发送 request 给服务器端; - 服务器端接收到 request 之后,可以针对某个/组客户端或所有客户端(广播)发送消息。 ![SignalR Hubs通信模型流程](http://doc.rdiframework.net/blog/article/20190814085207096.png) ## 4、SignalR的Hub连接类Mvc实现 ## 我们继续在[上一篇](http://www.guosisoft.com/article/detail/226)项目基础上扩展hubs的方式的使用。具体新增项目、添加signalr引用等可以参考上一篇。 **4.1、向工程中添加HubConnections目录,在其中添加ChatHub.cs文件,如下图所示:** ![新建charthub文件](http://doc.rdiframework.net/blog/article/20190814085250609.png) 代码内容如下: using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; namespace SignalRTestProj.HubConnections { //HubName 这个特性是为了让客户端知道如何建立与服务器端对应服务的代理对象, //如果没有设定该属性,则以服务器端的服务类名字作为 HubName 的缺省值 [HubName("chat")] public class ChatHub : Hub { public void Send(string clientName, string message) { // Call the addSomeMessage method to update clients. Clients.All.addSomeMessage(clientName, message); } } } 在上面的代码中,实现的服务很简单,就是当一个客户端调用Send方法向服务器发送message后,服务器端负责将该 message广播给所有的客户端(也可以给特定组或特定客户端),以实现聊天室的功能。 除了服务端可以向所有客户端通知调用客户端方法之外,还可以对其中想要发送的客户端进行限制。同时Clients这个属性有很多动态成员供我们使用: Clients.All:允许“调用”连接到此Hub上的所有客户端的一个方法 Clients.AllExcept:表示该调用必须发送给所有客户端,但是除了那些作为参数的connectionId以外。这里的参数可以是connectionId字符串、数组等 Clients.Caller 确定调用者的接收者是目前调用正在执行Hub方法的客户端 Clients.Client:将对方法的调用发送给指定connectionId的客户端,参数可以是字符串,也可以是数组 Client.Others :代表所有已连接的客户端,但是不包括正在调用该方法的客户端。 在方法中可以通过访问 this.Context.ConnectionId来获得当前掉用方法的客户端唯一标识符 1)、HubName 这个特性是为了让客户端知道如何建立与服务器端对应服务的代理对象,如果没有设定该属性,则以服务器端的服务类名字作为 HubName 的缺省值; 2)、ChatHub 继承自 Hub,从下面 Hub 的接口图可以看出:Hub 支持向发起请求者(Caller),所有客户端(Clients),特定组(Group) 推送消息。 ![Hub对象定义关系图](http://doc.rdiframework.net/blog/article/20190814085320974.png) 3)、public void Send(string clientName, string message) 这个接口是被客户端通过代理对象调用的; 4)、Clients 是 Hub 的属性,表示所有链接的客户端页面,它和 Caller一样是 dynamic,因为要直接对应到 Javascript 对象; 5)、Clients.All.addSomeMessage(clientName, message): 表示服务器端调用客户端的 addSomeMessage 方法,这是一个 Javascript 方法,从而给客户端推送消息。 **4.2、配置启动类** using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(SignalRTestProj.App_Start.ChartStartup))] namespace SignalRTestProj.App_Start { public class ChartStartup { public void Configuration(IAppBuilder app) { // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888 //1、 PersistentConnection 方式配置 //app.MapSignalR<ChatConnection>("/Connections/ChatConnection"); //2、hub方式配置 app.MapSignalR(); } } } **4.3、页面代码实现** <h2>Hub Chat</h2> <div> <input type="hidden" id="ClientName" value="@ViewBag.ClientName"/> <input type="text" id="msg" /> <input type="button" id="broadcast" value="广播" /> <br /> <h3> (<span id="MyClientName">@ViewBag.ClientName</span>): </h3> <ul id="messages"></ul> </div> @section scripts { <script src="~/Scripts/jquery-3.3.1.min.js"></script> <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script> <script src="~/signalr/hubs"></script> <script> $(function () { var chat = $.connection.chat; var myClientName = $('#ClientName').val(); chat.client.addSomeMessage = function (clientName, message) { writeMsg('<b>' + clientName + '</b> 对大家说: ' + message, 'event-message'); }; $('#msg').focus(); // 开始连接 $.connection.hub.start().done(function () { $('#broadcast').click(function () { // 调用send方法 chat.server.send(myClientName, $('#msg').val()); $('#msg').val('').focus(); }); }); //写消息 function writeMsg(eventLog, logClass) { var now = new Date(); var nowStr = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); $('#messages').prepend('<li class="' + logClass + '"><b>' + nowStr + '</b> ' + eventLog + '.</li>'); } }); </script> } 在上面的代码我们 1、首先获取客户端页面的名字; 2、然后通过 $.connection.chat 建立对应服务器端 Hub 类的代理对象 chat; 3、定义客户端的 Javascript 方法 addSomeMessage,服务器通过 dynamic 方式调用客户端的该方法以实现推送功能。在这里每当收到服务器推送来的消息,就在客户端页面的 messages 列表表头插入该消息。 4、当点击广播按钮时,客户端通过代理对象调用服务器端的 send 方法以实现向服务器发送消息。 5、通过 $.connection.hub.start(); 语句打开链接。 ## 5、效果展示 ## ![运行效果展示](http://doc.rdiframework.net/blog/article/20190814085345904.png) ## 6、代码下载 ## 实例源码可以移步github下载,地址:[https://github.com/yonghu86/SignalRTestProj](https://github.com/yonghu86/SignalRTestProj) ## 7、参考文章 ## - [RDIFramework.NET敏捷开发框架通过SignalR技术整合即时通讯(IM)](http://www.guosisoft.com/article/detail/229) - [史上最全面的SignalR系列教程-1、认识SignalR](http://www.guosisoft.com/article/detail/225) - [史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式](http://www.guosisoft.com/article/detail/226) - [Real-time ASP.NET with SignalR](https://dotnet.microsoft.com/apps/aspnet/signalr) - [微信公众号开发系列-玩转微信开发-目录汇总](http://www.guosisoft.com/article/detail/216) - [RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系列目录](http://www.guosisoft.com/article/detail/190) - [RDIFramework.NET ━ .NET快速信息化系统开发框架 ━ 工作流程组件介绍](http://www.guosisoft.com/article/detail/169) - [RDIFramework.NET框架SOA解决方案(集Windows服务、WinForm形式与IIS形式发布)-分布式应用](http://www.guosisoft.com/article/detail/189) - [RDIFramework.NET代码生成器全新V3.5版本发布-重大升级](http://www.guosisoft.com/article/detail/199) ----- 一路走来数个年头,感谢RDIFramework.NET框架的支持者与使用者,大家可以通过下面的地址了解详情。 RDIFramework.NET官方网站:http://www.rdiframework.net/ RDIFramework.NET官方博客:http://blog.rdiframework.net/ 同时需要说明的,以后的所有技术文章以官方网站为准,欢迎大家收藏! RDIFramework.NET框架由海南国思软件科技有限公司专业团队长期打造、一直在更新、一直在升级,请放心使用! 欢迎关注RDIFramework.net框架官方公众微信(微信号:guosisoft),及时了解最新动态。 扫描二维码立即关注 ![微信号:guosisoft](http://doc.rdiframework.net/weixin.png)
正文到此结束
本文标签:
.NET
消息交互
挨踢业界
RDIF.NET
版权声明:
本站原创文章,由
guosisoft.com
发布,遵循
CC 4.0 by-sa
版权协议,转载请附上原文出处链接和本声明。
上一篇
史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式
下一篇
史上最全面的SignalR系列教程-4、SignalR 自托管全解(使用Self-Host)-附各终端详细实例
热门推荐
{{article.title}}
热门指数:
浏览({{article.lookCount + 5000}})
相关文章
{{article.title}}
该篇文章的评论功能暂时被站长关闭
说给你听
本文目录
文章标签
RDIF.NET
其他
微信开发
.NET
消息交互
.NetCore
项目管理
常用工具
工作流
Web前端
数据库
挨踢业界
随机文章
史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式
Visual Studio 2019 正式发布,重磅更新,支持live share
2021 编程语言排行榜出炉!C#年度语言奖
团队项目开发"编码规范"之五:命名规范
RDIFramework.NET 快速开发框架 WebEasyUI版本 V6.0发布
RDIFramework.NET V3.3 WinForm版新增日程管理功能模块
史上最全面的SignalR系列教程-4、SignalR 自托管全解(使用Self-Host)-附各终端详细实例
VS2010+以上版本网站发布IIS详细步骤
.NET编译项目时出现《此实现不是 Windows 平台 FIPS 验证的加密算法的一部分》处理方法
值得一看的35个Redis常用问题总结
国思RDIF.vNext全新低代码快速开发框架平台6.1版本发布(支持vue2、vue3)
信息系统项目管理系列之二:项目生命期和组织
RDIFramework.NET ━ .NET敏捷开发框架V3.5版本全新发布 100%源码授权
RDIFramework.NET V3.3 Web版角色授权管理新增角色对操作权限项、模块起止生效日期的设置
ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
微信公众号开发C#系列-6、消息管理-普通消息接受处理
[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)
史上最全面的SignalR系列教程-6、SignalR 实现聊天室
.NET快速信息化系统开发框架 V3.2->Web版本工作流部分业务处理界面与查看界面全新展示
.NET快速信息化系统开发框架 V3.2-模块管理按子系统进行分类管理
网站信息
文章总数:599 篇
标签总数:8 个
分类总数:8 个
留言数量:1385 条
在线人数:
89
人
运行天数:1321天
最后更新:2023-05-18
QQ:406590790
13005007127