【C#】SignalR之主动推送信息的简单解决方案

432 阅读2分钟

我正在参加「掘金·启航计划」

在本篇文章中,将讲讲C#如何使用SignalR通讯
Core下的SignalR实现原理一样,只是写法不一样,主动推送消息的场景使用:页面登录后台管理系统,最新订单信息的通知等

1、信息推送效果

Form窗体下使用SignalR,通过页面客户端触发服务端,在服务端触发一次后,开启一个定时器,让定时器给加入到连接列表的客户端主动推送消息

image.png

2、主动推送,客户端和服务端相互判定

1)服务端关键代码


using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Timers;
 
namespace SignalRForm
{
    public class TestHub:Hub
    {
        #region 初始化 - 构造函数/以及服务
        public static bool isInite = false;
        public static List<string> list = null;
        Timer timer = null;
 
        static TestHub()
        {
            list = new List<string>();
 
            if (isInite)
            {
                Console.WriteLine("再次运行!");
            }
            
            //客户端第一个调用服务端方法时,执行一次构造函数
            Console.WriteLine("TestHub_Init");
        }
 
        public void MyTimer(object sender, ElapsedEventArgs e)
        {
            timer.Stop();
 
            Clients.Clients(list).getNowTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

            timer.Start();
        }
 
        public void initServer(string userGuid)
        {
            if (!isInite)
            {
                //读取txt文档内容
                string str;
                StreamReader sr = new StreamReader("d://template.txt", false);
                str = sr.ReadLine().ToString();
                sr.Close();
 
                if (!string.IsNullOrEmpty(str))
                {
                    string[] arr = str.Split(',');
                    foreach (string item in arr)
                    {
                        if (!string.IsNullOrEmpty(item))
                        {
                            list.Add(item);
                        }
                    }
                }
 
                isInite = true;
                timer = new Timer(1000); //每隔500毫米执行一次方法
                timer.Enabled = true;
                timer.Elapsed += MyTimer;
                if (list.Count > 0)
                    Clients.Clients(list).getNowTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            }
        }
        #endregion
 
        #region 客户端连接 - 服务器端监听
        public override Task OnConnected()
        {
            //将内容写入到txt文档
            StreamWriter sw = new StreamWriter("d://template.txt", true);
            sw.WriteLine(Context.ConnectionId + ",");
            sw.Close();
 
            list.Add(Context.ConnectionId);
 
            return base.OnConnected();
        }
        #endregion
 
        #region 客户端断开连接
        public override Task OnDisconnected(bool stopCalled)
        {
            //将内容写入到txt文档
            StreamWriter sw = new StreamWriter("d://templateout.txt", true);
            sw.WriteLine(Context.ConnectionId + ",");
            sw.Close();
 
            return base.OnDisconnected(stopCalled);
        }
        #endregion
 
        #region 客户端重新连接
        public override Task OnReconnected()
        {
            //将内容写入到txt文档
            StreamWriter sw = new StreamWriter("d://template.txt", true);
            sw.WriteLine("再次连接!" + isInite);
            sw.Close();
 
            return base.OnConnected();
        }
        #endregion
    }
}

2)客户端关键代码

<!DOCTYPE html>
<html style="height: 100%">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>测试SignalR主动推送</title>
    <script type="text/javascript" src="~/jQuery/jquery-2.0.0.min.js"></script>
    <script type="text/javascript" src="~/jQuery/jquery.signalR-2.2.0.min.js"></script>
    @*<script src="http://localhost:8686/signalr/hubs"></script>*@
    <script src="http://192.168.1.25:8686/signalr/hubs"></script>
 
    <style type="text/css">
 
        body, html {
            margin: 0;
            padding: 0;
        }
 
        /*-----clear-----*/
        .clear {
            *zoom: 1;
        }
 
            .clear:after {
                content: '';
                display: table;
                clear: both;
            }
    </style>
</head>
<body>
 
    <div id="nowTime"></div>
    <input id="runTime" type="hidden" />
</body>
</html>
 
<script type="text/javascript">
 
    var runTime = "";
    test();
    function test() {
 
        $(function () {
 
            try {
                //$.connection.hub.url = "http://localhost:8686/signalr"; //连接到SignalR服务端
                $.connection.hub.url = "http://192.168.1.25:8686/signalr"; //连接到SignalR服务端
 
                $.connection.hub.start().done(function (data) {
 
                    //服务端方法的回调函数:OnConnected、OnDisconnected、OnReconnected?
                    //在此方法初始化
                    chat.server.initServer("companyid");
                }).fail(function () {
                    console.log("实时消息服务连接失败!");
                });
 
                var chat = $.connection.testHub; //继承了Hub的类,用于客户端调用服务端类的方法
 
                //监听服务端方法判断是否初始化服务成功
                //chat.server.getNowTime(); //Connection must be started before data can be sent. Call .start() before .send()
                chat.client.getNowTime = function (data) {
                    
                    $("#runTime").val(data);
 
                    $("#nowTime").html(data);
                }
            }
            catch (ex) {
                console.log(ex);
            }
        });
    }
 
    setInterval(function () {
        
        if (runTime == $("#runTime").val()) {
            test();
        }
        else {
            runTime = $("#runTime").val();
        }
 
    }, 10 * 1000);
</script>

3、其他注意事项

1、可以先删除再添加【注意:最后一定要加斜杠】 netsh http delete urlacl url=http://localhost:8686/

2、添加网址【注意:最后一定要加斜杠】 netsh http add urlacl url=http://localhost:8686/ user=Everyone

3、查看所有使用到的端口

netstat -ano

image.png