.net mvc——后台主动向前台推送信息(signalr,没有前端调用)

主动推送消息有两种方案:

1.使用C#的signalr主动推送消息
2.使用ajax轮询,本质上还是前端向后端请求

这里采用signalr来实现主动的消息推送(无前端调用),同时结合前一篇博客的定时功能(.net mvc——定时任务实现),实现了服务端定时向前端推送消息,前端更新页面显示的功能。如果不懂signalr基础,可以参见C#——signalr实现简单的网页实时聊天

实现的效果如下:这里我是利用Timer进行定时,服务器后端每间隔一秒就向网页前端推送一次信息。
在这里插入图片描述

主要实现步骤及代码

1. 集线器Hub类(放在了新建的Hubs文件夹下,注意这里SendMsg方法与之前不同)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using TimerMvcWeb.Filters;

namespace TimerMvcWeb.Hubs
{
    [HubName("msgHub")]//客户端调用,首字母要小写
    public class MsgHub : Hub
    {
        public static int count = 0;
        [HubMethodName("sendMsg")]//客户端调用,首字母要小写
        public void SendMsg()
        {
            //因为在后台调用,所以要这样写,否则会出错,提示Using a Hub instance not created by the HubPipeline is unsupported
            var hubContext = GlobalHost.ConnectionManager.GetHubContext<MsgHub>();
            hubContext.Clients.All.getMsg("调用次数:" + count); //用户调用客户端的函数 
            count++;
            //Clients.All.getMsg("调用次数:"+count);
        }
    }
}
2.Startup类(也放在Hubs文件夹下)
using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

[assembly: OwinStartup(typeof(TimerMvcWeb.Hubs.Startup))]
namespace TimerMvcWeb.Hubs
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}
3.前端html代码

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>TimerMsgShow</title>
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/jquery.signalR-2.1.2.js"></script>
    <script src="/signalr/hubs"></script>
    <script>

        $(function () {
            serverClient();

        });

        //服务器连接操作
        function serverClient() {
            //注册服务器连接
            var msgHub = $.connection.msgHub;
            //2.给客户端注册方法,被服务器调用的方法,
            //服务器主动调用,给txt内容,客户端被动接收
            //接收到之后做什么
            msgHub.client.getMsg = function (txt) {

                var txtHtml = '<li><strong>' + htmlEncode(txt) + '</li>';
                $("#msgList").append(txtHtml);
                //alert(txt);
            }

            //3.启动连接并绑定处理事件
            $.connection.hub.start().done(function () {
                $("#sendBtn").removeAttr("disabled");
                console.info("start!");
                //$("#sendBtn").click(function () {
                //    msgHub.server.sendMsg(sessionStorage.getItem("user"), $("#txtMsg").val());
                //    //$('#txtMsg').val('').focus();
                //})
            }).fail(function () {

            });
        }
        // 将发来的信息转化为html标签以便添加到页面
        function htmlEncode(value) {
            var encodedValue = $('<div />').text(value).html();
            return encodedValue;
        }
    </script>
</head>
<body>
    <div id="msgList">

    </div>
    @*<input type="text" id="txtName" name="name" value="" />
    <button id="btnLogin">登录</button>*@
    <input type="text" id="txtMsg" name="name" value="" />
    <button id="sendBtn" disabled="disabled">发送消息</button>
</body>
</html>

4.定时任务调用集线器hub类的方法,需要先实现定时功能(参考https://blog.csdn.net/qq_35077107/article/details/104525704
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using TimerMvcWeb.Filters;
using TimerMvcWeb.Hubs;

namespace TimerMvcWeb.AutoTask
{
    /// <summary>
    /// 测试任务,从程序启动开始,每1秒执行一次
    /// </summary>
    [AutoTask(EnterMethod = "StartTask", IntervalSeconds = 1, StartTime = "")]
    public class TestTask
    {

        public static void StartTask()
        {
            //调用集线器方法,向前台发送消息
            MsgHub hub = new MsgHub();
            hub.SendMsg();
           
           
        }
    }
}

如果不用定时只推送一次消息,也可以在Global.asax的Application_Start() 函数创建线程类的事例。这样网站启动时线程就启动了。

但这里有一个小问题:

当我的服务器只向前端推送一次消息时,我打开相应的网页往往收不到消息的推送,调试后发现主动推送的代码确实是执行了。

原因:
原因应该是网页的加载没有主动推送代码执行的快,当服务器调用客户端方法时,网页还未加载完成,所以推送的消息在网页上还显示不出来。

解决办法:
将定时推送的时间间隔加大为两秒后推送消息时,网页就能正常收到推送的消息。

参考:
MVC3 使用SingalR后台推送数据

获取Hub集线器实例的方式
利用SignalR实现实时推送信息功能

发布了68 篇原创文章 · 获赞 12 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_35077107/article/details/104602643
今日推荐