史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式

1、概述

通过前两篇

史上最全面的SignalR系列教程-1、认识SignalR

史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式

RDIFramework.NET敏捷开发框架通过SignalR技术整合即时通讯(IM)

文章对SignalR的介绍,我们对SignalR已经有了全面的认识。SignalR API 客户端和服务器端持久连接的通信方式,一次连接代表一个发送单个、分组或者广播消息的简单终端。持久连接的API(表现在.NET的PersistentConnection 类上)给了开发人员低价访问SignalR所暴露的通信协议的条件。使用这种连接方式,就像开发人员使用WCF一样。

本篇将继续在上一篇的基础上,讲解SignalR通过最常用的集线器方式实现消息推送与发送。
我们知道SignalR的通信模型主要是两类Persistent Connections与Hubs。Hub是一种更高级的管道,它在连接协议上允许客户端和服务器端能够直接调用彼此的方法。SignalR的这种自动分发跨机器边界调度的方法就像施了魔法一样,让客户端调用服务端的方法像调用本地一样简单,反之亦然。使用Hub的模式就像开发人员使用远程API一样,比如 .NET Remoting。使用Hub同样能够让你传递类型化的参数到方法上进行模型绑定。通过Hubs实现服务端消息推送到客户端,抽象结构图如下。

SignalR Hub 结构流程图

2、SignalR Hub 原理分析

SignalR具体是如何到达实行性的呢?SignalR 的实现机制与 .NET WCF 或 Remoting 是相似的,都是使用远程代理来实现。SignalR 将整个连接,信息交换过程封装得非常漂亮,客户端与服务器端全部使用 JSON 来交换数据。

当服务端的代码访问一个客户端的方法时,一个数据包被自动传输,数据包中包含了函数方法参数的名称(如果是一个对象,那么这个对象会被序列化成JSON)。客户端然后根据客户端的代码匹配方法的名称。如果找到相应的匹配方法,那么久调用相应的函数执行反序列化的参数。

3、Hubs实现实时消息流程

  • 在服务器端定义对应的hub class;

  • 在客户端定义hub class 所对应的 proxy 类;

  • 在客户端与服务器端建立连接(connection);

  • 然后客户端就可以调用 proxy 对象的方法来调用服务器端的方法,也就是发送 request 给服务器端;

  • 服务器端接收到 request 之后,可以针对某个/组客户端或所有客户端(广播)发送消息。

SignalR Hubs通信模型流程

4、SignalR的Hub连接类Mvc实现

我们继续在上一篇项目基础上扩展hubs的方式的使用。具体新增项目、添加signalr引用等可以参考上一篇。

4.1、向工程中添加HubConnections目录,在其中添加ChatHub.cs文件,如下图所示:

新建charthub文件

代码内容如下:

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对象定义关系图

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、效果展示

运行效果展示

6、代码下载

实例源码可以移步github下载,地址:https://github.com/yonghu86/SignalRTestProj

7、参考文章


一路走来数个年头,感谢RDIFramework.NET框架的支持者与使用者,大家可以通过下面的地址了解详情。

RDIFramework.NET官方网站:http://www.rdiframework.net/

RDIFramework.NET官方博客:http://blog.rdiframework.net/

同时需要说明的,以后的所有技术文章以官方网站为准,欢迎大家收藏!

RDIFramework.NET框架由海南国思软件科技有限公司专业团队长期打造、一直在更新、一直在升级,请放心使用!

欢迎关注RDIFramework.net框架官方公众微信(微信号:guosisoft),及时了解最新动态。

扫描二维码立即关注

微信号:guosisoft

posted on 2019-08-13 11:26  .NET快速开发框架 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/huyong/p/11344828.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
教程将向您介绍使用ASP.NET SignalR 2和ASP.NET MVC 5进行实时Web应用程序开发。本教程使用与SignalR入门教程相同的聊天应用程序代码,但演示如何将其添加到MVC 5应用程序。 在这个主题中,您将学习以下SignalR开发任务: 将SignalR库添加到MVC 5应用程序。 创建集线器和OWIN启动来将内容推送到客户端。 在网页中使用SignalR jQuery库来发送消息并从集线器显示更新。 以下屏幕截图显示了在浏览器中运行的已完成的聊天应用程序。 聊天实例 部分: 设置项目 运行示例 检查代码 下一步 设置项目 先决条件: Visual Studio 2013.如果您没有Visual Studio,请参阅ASP.NET下载以获取免费的Visual Studio 2013 Express开发工具。 本节介绍如何创建ASP.NET MVC 5应用程序,添加SignalR库以及创建聊天应用程序。 在Visual Studio中,创建一个面向.NET Framework 4.5的C#ASP.NET应用程序,将其命名为SignalRChat,然后单击确定。 创建网页 在New ASP.NET Project对话框中选择MVC,然后点击Change Authentication。 创建网页 在更改身份验证对话框中选择无身份验证,然后单击确定。 选择不验证 注意 如果您为您的应用程序选择不同的身份验证提供程序,Startup.cs则将为您创建一个班级; 您将不需要Startup.cs在下面的第10步中创建自己的课程。 在“ 新建ASP.NET项目”对话框中单击确定。 打开工具| 库包管理器| 程序包管理器控制台并运行以下命令。此步骤向项目添加了一组启用SignalR功能的脚本文件和程序集引用。 install-package Microsoft.AspNet.SignalR 在解决方案资源管理器中,展开脚本文件夹。请注意,SignalR的脚本库已添加到项目中。 脚本文件夹 在解决方案资源管理器中,右键单击该项目,选择添加| 新建文件夹,并添加一个名为Hubs的新文件夹。 用鼠标右键单击该Hubs文件夹,单击添加| 新建项目,选择Visual C#| Web | SignalR节点安装窗格中,从中心窗格中选择SignalR Hub Class(v2),并创建一个名为ChatHub.cs的新中心。您将使用此作为将消息发送到所有客户端的SignalR服务器中心。 创建新的中心 用下面的代码替换ChatHub中的代码。 C# 复制 using System; using System.Web; using Microsoft.AspNet.SignalR; namespace SignalRChat { public class ChatHub : Hub { public void Send(string name, string message) { // Call the addNewMessageToPage method to update clients. Clients.All.addNewMessageToPage(name, message); } } } 创建一个名为Startup.cs的新。将文件的内容更改为以下内容。 C# 复制 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(); } } } 编辑HomeController在Controllers / HomeController.cs中找到的,并将以下方法添加到中。此方法返回您将在稍后的步骤中创建的聊天视图。 C# 复制 public ActionResult Chat()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值