C# SignalR 实现数据实时传输

 

上次我们用websocket做了一个后端实时传输数据的例子websocket 传输实时数据到前端,并用 Echart 动态展示数据,这次我打算换成SignalR来做数据传输试试。

SignalR 这个机制让后端可以主动调用前端的方法,在实际开发中解决了很多问题。比如说数据库进行了更新,但是前端并不知道,并不能实时反应出数据库的实时数据。这时候在后端更新数据库的逻辑中加入调用前端获取数据的方法,这时前端变受到后端的驱动进行数据更新,从而只要数据库有变化前端就会实时更新。

首先我们在服务器端的console项目中来建立一个hub,里边可以定义前端的方法供后端调用,也可定义后端的方法供前端调用:

public class DataHub : Hub
    {
        public DataHub()
        {
            Program.dataHub = this;
        }

        public void Push(string data)
        {
            Clients.All.Push(data);
        }

        public void SetCmd(string cmd)
        {
            Program.Cmd = cmd;
        }


        public override Task OnConnected()
        {
            return base.OnConnected();
        }

        public override Task OnDisconnected(bool stopCalled)
        {
            return base.OnDisconnected(stopCalled);
        }
    }

        Push方法为后端调用前端的方法,若后端执行push方法,则让所有与此hub相连接的的前端都执行自己的Push方法。SetCmd是后端的方法,它设定后端的Cmdproperty的值,所以一旦前端调用此方法可以改变后端Cmd的值。

        之后我们要将hub部署到本地,做一些基本的配置:

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;

namespace signalr
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR(new HubConfiguration() { EnableJSONP = true });
        }
    }
}

        先解决跨域问题,再之后部署signalR。

static void Main(string[] args){
    WebApp.Start<Startup>("http://localhost:8000");
}

        那么这样一来signalr的hub就配置好了。我打算后端不停的去推送一些实时的随机数据,让前端以echart图表的方式展现出来。并当前端喊停时停止推送,具体代码如下:

using Microsoft.Owin.Hosting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;

namespace signalr
{
    public class Program
    {
        public static DataHub dataHub { get; set; }
        public static string Cmd { get; set; }
        private static string ConvertObjectToString(Data obj)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
            MemoryStream memoryStream = new MemoryStream();
            serializer.WriteObject(memoryStream, obj);

            string json = Encoding.Default.GetString(memoryStream.ToArray());
            return json;
        }

        static void Main(string[] args)
        {

            WebApp.Start<Startup>("http://localhost:8000");
            while(true)
            {
                if (Cmd == "ACD")
                {
                    while (Cmd == "ACD")
                    {
                        Thread.Sleep(300);
                        Data a = new Data()
                        {
                            x = new List<int>(),
                            y = new List<int>()
                        };
                        Random r = new Random();
                        for (int i = 1; i < 100; i++)
                        {
                            a.x.Add(i);
                            a.y.Add(r.Next(1, 100));
                        }

                        dataHub.Push(ConvertObjectToString(a));
                    }
                }
                else if (Cmd == "STOP")
                {
                    Cmd = string.Empty;
                }
            }
        }
    }
}

        至此后端代码就完成了,接下来就是前端,首先前端代码需要引用echart,jquery,signalr以及后端给前端的咱们自定义的hub代码,这样前后端才能都知道互相暴露出的方法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="./echarts.js"></script>
    <script src="./jquery-1.6.4.min.js"></script>
    <script src="./jquery.signalR-2.4.3.min.js"></script>
    <script src="http://localhost:8000/signalr/hubs"></script>
    <script src="./main.js" defer></script>
    <title>signalR data</title>
</head>
<body>
    <div id="main-chart" style="width: 600px;height:400px;"></div>
    <button class="btn_close">close</button>
</body>
</html>

        值得注意的时jquery的版本不能低于1.6哦,不然执行不了signalR。我将jquery.signalR-2.4.3.min.js上传了,大家可以来这里免费下载

        前端的JS代码也是非常的简单,初始化echart,连接到hub,初始化Push方法,并调用后端setCmd方法改变Cmd来让后端开始push实时数据。点击按钮时将Cmd设置为“STOP” 后端便停止推送:

let myChart = echarts.init(document.getElementById('main-chart'));

let option = {
    title: {
      text: 'ECharts real time chart!!!'
    },
    tooltip: {},
    legend: {
      data: ['y']
    },
    xAxis: {
      data: []
    },
    yAxis: {},
    series: [
      {
        name: 'y',
        type: 'bar',
        data: []
      }
    ]
  };


let btn = document.getElementsByClassName('btn_close');

let hub = $.connection.dataHub;
//连接到dataHub上
$.connection.hub.url = "http://localhost:8000/signalr";
//设置前端的Push方法
hub.client.Push = function(data)
{
    let jsonData = JSON.parse(data);
    option.xAxis.data = jsonData.x;
    option.series[0].data = jsonData.y;
    myChart.setOption(option);
}
//一旦连接到dataHub后就调用后端setCmd方法,从而让后端开始推送数据
$.connection.hub.start().done(function () {
  hub.server.setCmd("ACD");
});
//停止按钮:设置Cmd为STOP来停止推送
btn[0].addEventListener("click",function(){hub.server.setCmd("STOP");});

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go_with_dream

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值