zoukankan      html  css  js  c++  java
  • C# ASP.NET MVC 之 SignalR 学习 实时数据推送显示 配合 Echarts 推送实时图表

    本文主要是我在刚开始学习 SignalR 的技术总结,网上找的学习方法和例子大多只是翻译了官方给的一个例子,并没有给出其他一些经典情况的示例,所以才有了本文总结,我在实现推送简单的数据后,就想到了如何去推送复杂的数据,以及推送一个实时的图表数据,文本为我原创,转载请注明出处:Richard.Hu,先上一堆乱七八糟的说明先:

    SignalR的官方地址是: https://www.asp.net/signalr

    网上给出例子是一个聊天的例子,官网地址是:https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr

    聊天的例子是啥意思呢,就是任何一个浏览器客户端发送数据给服务器之后,服务器收到数据然后群发给所有人。这确实是一个经典的例子,所以这次我的研究就不考虑这种情况了,考虑另一种经典的情况,叫做实时数据推送。这是什么意思呢,意思是你的系统有一些实时数据需要不停的在客户端显示,在没有SignalR的时候,ASP.NET基本只能通过不停的ajax轮询刷新数据,无论是服务器端还是客户端,都会带来极大的性能考验。

    好了,开始今天的学习之旅,我所依赖的开发环境是Visual Studio 2017,如果不是这个IDE,不保证完全正确的。

    1. 创建没有身份验证的ASP.NET MVC项目


    这就完成第一步了,创建好了一个项目。

    2. 安装SignalR组件,通过nuget方式安装


    安装的过程没有什么好说的,就是一路无脑安装就可以了,安装完成之后就出现了界面说明,这个说明还是值得看看的,原版如下:

    Please see http://go.microsoft.com/fwlink/?LinkId=272764 for more information on using SignalR.
    
    Upgrading from 1.x to 2.0
    -------------------------
    Please see http://go.microsoft.com/fwlink/?LinkId=320578 for more information on how to 
    upgrade your SignalR 1.x application to 2.0.
    
    Mapping the Hubs connection
    ----------------------------
    To enable SignalR in your application, create a class called Startup with the following:
    
    using Microsoft.Owin;
    using Owin;
    using MyWebApplication;
    
    namespace MyWebApplication
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR();
            }
        }
    } 
    
    Getting Started
    ---------------
    See http://www.asp.net/signalr/overview/getting-started for more information on how to get started.
    
    Why does ~/signalr/hubs return 404 or Why do I get a JavaScript error: 'myhub is undefined'?
    --------------------------------------------------------------------------------------------
    This issue is generally due to a missing or invalid script reference to the auto-generated Hub JavaScript proxy at '~/signalr/hubs'.
    Please make sure that the Hub route is registered before any other routes in your application.
     
    In ASP.NET MVC 4 you can do the following:
     
          <script src="~/signalr/hubs"></script>
     
    If you're writing an ASP.NET MVC 3 application, make sure that you are using Url.Content for your script references:
     
        <script src="@Url.Content("~/signalr/hubs")"></script>
     
    If you're writing a regular ASP.NET application use ResolveClientUrl for your script references or register them via the ScriptManager 
    using a app root relative path (starting with a '~/'):
     
        <script src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script>
     
    If the above still doesn't work, you may have an issue with routing and extensionless URLs. To fix this, ensure you have the latest 
    patches installed for IIS and ASP.NET. 
    

     仔细阅读下,里面说了好多东西,我先大致的说下,等全部演示一遍后,再回来看就印象深刻:

    1. 映射Hubs连接,需要创建一个startup类,并粘贴上面的代码

    2. 里面有个SignalR自动生成的代理HUB,在路径'~/signalr/hubs'里面,然后再ASP.NET MVC5中需要使用

    <script src="~/signalr/hubs"></script>
    

    其他的就没有什么东西了,接下来就改造这个项目了。

    3. 改造 Index.cshtml 文件


    我们目的很明确,在这里显示服务器推送的数据,就简单处理了,其他的一堆东西都不要了

    @{
        ViewBag.Title = "Home Page";
    }
    
    
    
    <div id="test">这里即将显示服务器推送的数据</div>
    

     这时候可以尝试的运行一下

    emmmmmmmmm,谈了一堆错误,没关系,那就看看这是什么错误,

    1. 没有 OwinStartupAttribute 属性

    2. 没有 Startup.cs 类

    这不就是我们第二步里提到的东西么,那就先按照他的意思这么办好了

    4. 创建 Startup.cs 文件


    我们就创建一个类文件,放的位置就是项目的下面,然后复制代码

    然后,粘贴下面的代码,反正官方就是这么要求的

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Microsoft.Owin;
    using Owin;
    
    [assembly: OwinStartup( typeof( WebApplication1.Startup ) )]
    
    namespace WebApplication1
    {
        public class Startup
        {
    
            public void Configuration( IAppBuilder app )
            {
                // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888  
                app.MapSignalR( );
    
            }
        }
    }
    

    然后我们在运行看看效果:

    哈哈,看到可以了,接下来就准备真的数据推送了。

    4. 创建 MyHub.cs 文件


    我们就创建一个文件夹,Hubs然后再添加一个文件,就命名成 MyHub.cs

    然后把下面的代码拷贝进去:

    using Microsoft.AspNet.SignalR;
    using Microsoft.AspNet.SignalR.Hubs;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Web;
    
    namespace WebApplication1.Hubs
    {
        [HubName( "myHub" )]
        public class MyHub : Hub
        {
            // Is set via the constructor on each creation
            private Broadcaster _broadcaster;
    
    
            public MyHub( )
                : this( Broadcaster.Instance )
            {
    
            }
    
            public MyHub( Broadcaster broadcaster )
            {
                _broadcaster = broadcaster;
    
            }
    
        }
    
    
        /// <summary>
        /// 数据广播器
        /// </summary>
        public class Broadcaster
        {
            private readonly static Lazy<Broadcaster> _instance =
                new Lazy<Broadcaster>( ( ) => new Broadcaster( ) );
    
            private readonly IHubContext _hubContext;
    
    
    
            private Timer _broadcastLoop;
    
            public Broadcaster( )
            {
                // 获取所有连接的句柄,方便后面进行消息广播
                _hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>( );
                // Start the broadcast loop
                _broadcastLoop = new Timer(
                    BroadcastShape,
                    null,
                    1000,
                    1000 );
    
            }
    
    
            private Random random = new Random( );
    
    
            private void BroadcastShape( object state )
            {
                // 定期执行的方法
    
            }
    
    
    
            public static Broadcaster Instance
            {
                get
                {
                    return _instance.Value;
                }
            }
        }
    }
    

     里面已经包含了一个Hub集线器了,然后设置了一个统一的静态 Broadcaster 数据广播对象,之后我们要进行的操作都在 private void BroadcastShape( object state ) 方法里操作就可以了,现在我们要推送一个随机数,0-1000的随机数,然后方法怎么写呢,参照下面

            private void BroadcastShape( object state )
            {
                // 定期执行的方法
                _hubContext.Clients.All.sendTest1( random.Next( 1000 ).ToString( ) );
            }
    

    OK,那么我们服务器端已经写完了,接下来要在客户端显示了,回到 index.cshtml 的页面上看看

    @{
        ViewBag.Title = "Home Page";
    }
    
    
    
    <div id="test">这里即将显示服务器推送的数据</div>
    
    
    @section scripts {
        <script src="~/Scripts/jquery.signalR-2.2.3.min.js"></script>
        <script src="~/signalr/hubs"></script>
        <script>
            $(function () {
                var mypush = $.connection.myHub;
    
                mypush.client.sendTest1 = function (message) {
                    $("#test").text(message);
                    console.log(message);
                };
    
                $.connection.hub.start();
    
    
    
            });
        </script>
    }
    

     这里的两个js库都是必须引用的,特别是第二个,前面的文档是已经说明了,下面的js代码就是获取hub代理,然后绑定消息。然后就可以运行了。

     注意第一个引用的JS,jquery.signalR-2.2.3.min.js   这里面有个版本号信息,需要和你安装的版本号对应,不然就找不到这个js了,如果你安装了2.3.0版本,那么这里就要写jquery.signalR-2.3.0.min.js

     

    可以看到这个值确实是变了,我们再点击F12看看里面的东西,发现确实有hubs.js文件存在,里面包含了myhub的代理。

    5. 推送JSON数据


    上面已经演示了一个推送字符串的操作了,如果我们要推送一个复杂的数据怎么办,我们以一个徽章显示作为示例

    服务器的代码:

            private void BroadcastShape( object state )
            {
                JObject json = new JObject( );
                json.Add( "A", random.Next( 1000, 10000 ).ToString( ) );
                json.Add( "B", random.Next( 20 ).ToString( ) );
                // 定期执行的方法
                _hubContext.Clients.All.sendTest1( json );
            }
    

    Index.cshtml代码

    @{
        ViewBag.Title = "Home Page";
    }
    
    
    <button class="btn btn-primary" type="button" id="test1">
        Messages <span class="badge" id="test2">4</span>
    </button>
    
    
    @section scripts {
        <script src="~/Scripts/jquery.signalR-2.2.3.min.js"></script>
        <script src="~/signalr/hubs"></script>
        <script>
            $(function () {
                var mypush = $.connection.myHub;
    
                mypush.client.sendTest1 = function (json) {
                    $("#test1").html(json.A + '<span class="badge">' + json.B+'</span>');
                    console.log(message);
                };
    
                $.connection.hub.start();
    
    
    
            });
        </script>
    }
    

    然后再运行,发现:

    发现这个还不够过瘾,我想动态显示图表怎么办,比如说柱形图

    6. 实时柱形图


    柱形图的插件我们选择开源的 echart 图表,百度的作品,非常给力,官网地址:http://echarts.baidu.com/   下面随便放点这个插件的图表示例

    我们下载这个js文件,

    然后把这个js文件添加到项目中去,就如下面一样

    然后修改服务器的推送方法

            private void BroadcastShape( object state )
            {
                int[] values = new int[10];
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = random.Next( 100 );
                }
                // 定期执行的方法
                _hubContext.Clients.All.sendTest1( values );
            }
    

    修改客户端的Index.cshtml代码

    @{
        ViewBag.Title = "Home Page";
    }
    
    
    <div id="test" style="height:600px"></div>
    
    
    @section scripts {
        <script src="~/Scripts/jquery.signalR-2.2.3.min.js"></script>
        <script src="~/Scripts/echarts.min.js"></script>
        <script src="~/signalr/hubs"></script>
        <script>
            $(function () {
    
                var myChart1 = echarts.init(document.getElementById('test'));
                myChart1.setOption({
                    title: {
                        text: '实时数据加载示例'
                    },
                    tooltip: {},
                    legend: {
                        data: ['销量']
                    },
                    xAxis: {
                        data: ["衬衫", "羊毛", "雪纺", "裤子", "高跟", "袜子", "袖子", "领子", "袜子", "脑子"]
                    },
                    yAxis: {},
                    series: [{
                        name: '销量',
                        type: 'bar',
                        data: []
                    }]
                });
    
    
    
    
    
                var mypush = $.connection.myHub;
    
                mypush.client.sendTest1 = function (array) {
                    myChart1.setOption({
                        series: [{
                            data: array
                        }]
                    });
                    console.log(array);
                };
    
                $.connection.hub.start();
    
    
    
            });
        </script>
    }
    

     然后就可以运行程序看到想要的效果了。

    可以看懂动态变化的图表数据了,其他的动态图表也是类似的,参照这个就可以实现了,思路都是一致的。文本就到这里为止。

  • 相关阅读:
    VysorPro助手
    Play 2D games on Pixel running Android Nougat (N7.1.2) with Daydream View VR headset
    Play 2D games on Nexus 6P running Android N7.1.1 with Daydream View VR headset
    Native SBS for Android
    ADB和Fastboot最新版的谷歌官方下载链接
    How do I install Daydream on my phone?
    Daydream Controller手柄数据的解析
    蓝牙BLE传输性能及延迟分析
    VR(虚拟现实)开发资源汇总
    Android(Java)控制GPIO的方法及耗时分析
  • 原文地址:https://www.cnblogs.com/dathlin/p/9026680.html
Copyright © 2011-2022 走看看