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

31 篇文章 1 订阅
29 篇文章 0 订阅

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

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实现实时推送信息功能

在 ASP.NET MVC 中使用 SignalR 实现推送功能需要以下步骤: 1. 在 Visual Studio 中创建一个 ASP.NET MVC 项目。 2. 通过 NuGet 安装 SignalR 库。 3. 创建一个 SignalR Hub 类。Hub 类是用来处理客户端和服务器之间的连接和消息传递的核心组件。 4. 在 Startup.cs 中配置 SignalR 中间件。 5. 在客户端 JavaScript 中引用 SignalR 库,并连接到 SignalR Hub。 6. 在 SignalR Hub 中定义需要推送的消息方法,然后在服务器端调用该方法以向客户端发送消息。 下面是一个简单的示例: 1. 创建一个名为 ChatHub 的 SignalR Hub 类: ```csharp using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace MvcSignalR.Hubs { public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } } } ``` 2. 在 Startup.cs 中配置 SignalR 中间件: ```csharp using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using MvcSignalR.Hubs; namespace MvcSignalR { public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSignalR(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseStaticFiles(); app.UseSignalR(routes => { routes.MapHub<ChatHub>("/chathub"); }); app.UseMvcWithDefaultRoute(); } } } ``` 3. 在客户端 JavaScript 中引用 SignalR 库,并连接到 SignalR Hub: ```javascript <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="/lib/signalr/dist/browser/signalr.js"></script> <script> var connection = new signalR.HubConnectionBuilder().withUrl("/chathub").build(); connection.start().then(function () { console.log("connected"); }).catch(function (err) { return console.error(err.toString()); }); connection.on("ReceiveMessage", function (user, message) { console.log(user + " says " + message); }); $("#sendButton").click(function () { var user = $("#userInput").val(); var message = $("#messageInput").val(); connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); }); </script> ``` 4. 在 SignalR Hub 中定义需要推送的消息方法,然后在服务器端调用该方法以向客户端发送消息。 在这个示例中,当客户端调用 SendMessage 方法时,服务器将向所有连接的客户端发送 ReceiveMessage 消息。 以上就是在 ASP.NET MVC 中使用 SignalR 实现推送功能的基本步骤。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值