zoukankan      html  css  js  c++  java
  • 史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式

    1、概述

    通过上篇史上最全面的SignalR系列教程-1、认识SignalR文章的介绍,我们对SignalR技术已经有了一个全面的了解。本篇开始就通过SignalR的典型应用的实现方式做介绍,例子虽然简单,但麻雀虽小五脏俱全。可以以此为基础,扩展到实际应用中。

    SignalR 的实现机制与.NET WCF 或 Remoting 是相似的,都是使用远程代理来实现。在具体使用上,有两种不同通信模型:PersistentConnection 和 Hubs,其中 PersistentConnection 是实现了长时间的 Javascript 轮询(类似于 Comet),Hub 是用来解决实时信息交换问题,它是利用 Javascript 动态载入执行方法实现的。SignalR 将整个连接,信息交换过程封装得非常漂亮,客户端与服务器端全部使用 JSON 来交换数据。

    对于这两种方式的讨论,感兴趣的朋友可以移步:https://stackoverflow.com/questions/9280484/signalr-why-choose-hub-vs-persistent-connection

    本篇主要介绍使用SignalR的永久连接类(Persistent Connections)的实现方式来实现消息推送(广播)功能,分别以Asp.NET MVC与控制台程序做实例演示。对于Hubs这种集线器的实现方式在下篇文章介绍。

    2、SignalR的永久连接类Mvc实现

    在ASP.NET MVC下实现SignalR的永久连接类非常的简单,只需简单4步就可以实现一个简单的群聊功能。

    2.1、 创建ASP.NET Mvc项目

    2.2、安装Nuget包

    创建好项目后,要使用SignalR,需要先安装SignalR包,可以通过程序包管理控制台输入包安装命令进行安装。

    Install-Package Microsoft.AspNet.SignalR
    

    也可以使用界面方式,如下图所示。

    安装SignalR包-Microsoft.AspNet.SignalR

    2.3、增加SignalR服务

    规划适当的SignalR服务文件存放的文件夹,如我们放在Connections文件夹中,在此文件夹右键选择新建项,我们选择SignalR Persistent Connection Class永久连接类项。

    添加SignalR服务

    确定后,VS会自动给我们生成对应代码,如下:

    using System.Threading.Tasks;
    using Microsoft.AspNet.SignalR;
     
    namespace SignalRTestProj_1.Connections
    {
        public class ChatConnection : PersistentConnection
        {
            protected override Task OnConnected(IRequest request, string connectionId)
            {
                return Connection.Send(connectionId, "Welcome!");
            }
     
            protected override Task OnReceived(IRequest request, string connectionId, string data)
            {
                return Connection.Broadcast(data);
            }
        }
    }
    

    我们对代码做适当修改,让业务更人性化,如下所示:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    
    
    namespace SignalRTestProj_1.Connections
    {
        using Microsoft.AspNet.SignalR;
    
        public class ChatConnection : PersistentConnection
        {
            private static int _connections = 0;
    
            protected override Task OnConnected(IRequest request, string connectionId)
            {
                Interlocked.Increment(ref _connections);
                //广播消息
                Connection.Broadcast("新的连接加入,连接ID:" + connectionId + ",已有连接数:" + _connections);
                return Connection.Send(connectionId, "双向连接成功,连接ID:" + connectionId);
            }
    
            /// <summary>
            /// 连接断开 
            /// </summary>
            protected override Task OnDisconnected(IRequest request, string connectionId, bool stopCalled)
            {
                Interlocked.Decrement(ref _connections);
                return Connection.Broadcast(connectionId + "退出连接,已有连接数:" + _connections);
            }
    
            protected override Task OnReceived(IRequest request, string connectionId, string data)
            {
                var message = connectionId + "发送内容>>" + data;
                return Connection.Broadcast(message);
            }
        }
    }
    

    2.4、启动路由注册

    要使Signal启作用,我们必须启动路由注册,要让客户端能找到,我们使用Owin。如下图所示,我们添加一个Owin Start启动类。

    增加Startup启动类

    using Microsoft.Owin;
    using Owin;
    using SignalRTestProj_1.Connections;
    
    [assembly: OwinStartup(typeof(SignalRTestProj_1.App_Start.ChartStartup))]
    
    namespace SignalRTestProj_1.App_Start
    {
        public class ChartStartup
        {
            public void Configuration(IAppBuilder app)
            {
                // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888
                // 配置上文实现的ChatConnections
                app.MapSignalR<ChatConnection>("/Connections/ChatConnection");
            }
        }
    }
    

    至此,我们服务端就算搭建起来了,现在我们增加一个页面来实现调用。

    2.5、前端界面处理

    前端js实现消息广播,并实时记录

    <html>
    	<head>
    	    <meta name="viewport" content="width=device-width" />
    	    <title>SignalR永久连接类 Demo</title>
    	    <script src="~/Scripts/jquery-3.3.1.min.js"></script>
    	    <script src="~/Scripts/jquery.signalR-2.4.1.min.js"></script>
    	</head>
    	<body>
    	    <div>
    	        <h1>SignalR永久连接类 Demo</h1>
    	        <div>
    	            <input type="text" id="msgContext" placeholder="请输入消息内容...." />
    	            <button id="sendMessage" class="btn-primary">Send</button>            
    	            <ul id="messages"></ul>
    	        </div>
    	        <script>
    	            var connection = $.connection("/Connections/ChatConnection");
    	            connection.logging = true;
    	            //客户端接收消息
    	            connection.received(function (data) {
    	                $('#messages').append('<li>' + data + '</li>');
    	            });
    	            //连接错误处理
    	            connection.error(function (err) {
    	                alert('与服务器连接报错:'+ err.message);
    	            });
    	            //连接成功
    	            connection.start().done(function () {
    	                $('#sendMessage').click(function () {
    	                    var val = $('#msgContext').val();
    	                    //向服务器端发送消息
    	                    connection.send(val);
    	                });
    	            });
    	        </script>
    	    </div>
    	</body>
    </html>
    

    OK,全面完成,F5运行看效果吧。

    2.6、效果展示

    3、控制台做SignalR服务端实现

    除了Web实时应用之外,我们还可以用其他应用程序实现实时交互,如控制台。
    只需要Install-Package Microsoft.AspNet.SignalR.Client命令,示例代码如下:

    using Microsoft.AspNet.SignalR.Client;
    using static System.Console;
    
    namespace ClientWithSignalRDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                var connection = new Connection("http://localhost:65309/Connections/ChatConnection");
    
                connection.Received += WriteLine;
                connection.Start().Wait();
    
                string line;
                while ((line = ReadLine()) != null)
                {
                    connection.Send(line).Wait();
                }
            }
        }
    }
    

    4、代码下载

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

    5、参考文章


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

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

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

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

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

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

    扫描二维码立即关注

    微信号:guosisoft

  • 相关阅读:
    List、Set、Map集合大杂烩
    Android的DatePicker和TimePicker-android学习之旅(三十八)
    Ubuntu 启动项、菜单 改动 防止隐藏
    Ehcache 整合Spring 使用页面、对象缓存
    Spring MVC 相关资料整理
    Spring + Spring MVC+Hibernate框架整合详细配置
    @RequestMapping 用法详解之地址映射
    关于时间统计问题
    Oracle之物化视图
    Oracle:高效插入大量数据经验之谈
  • 原文地址:https://www.cnblogs.com/huyong/p/11338589.html
Copyright © 2011-2022 走看看