通过 SignalR 实现耗时任务实时通知

简述

ASP.NET SignalR 是一个为 ASP.NET 开发者提供的简化 real-time web 应用的库。简化并优化以往 Web 程序耗资源 javascript轮询,以及 Comet Programming 方案,同时为 Web程序 添加了即时能力(realtime)。

ASP.NET SignalR 出现后就受到广泛的关注。目前已经到升级到2.0,需要 .NET Framework 4.5.支持。

目标

利用 ASP.NET SignalR 实现一个服务器端执行一个耗时任务,执行完通知客户端的例子。

实现

第一步:安装 ASP.NET SignalR

通过 Nuget 安装 ASP.NET SignalR

Install-Package Microsoft.AspNet.SignalR

安装内容包括 ASP.NET SignalR,Microsoft.AspNet.SignalR.JS 2.0.0,以及相关依赖。

第二步:注册 SignalR的中间件


using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(RealtimeNotifier.Startup))]

namespace RealtimeNotifier
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
            app.MapSignalR();
        }
    }
}

通过注册中间件,注册了客户端访问服务端 Hub 的路由。默认路由地址 /signalr/hubs,既客户端通过代理生成 javascript 文件的地址。

可以通过配置修改默认地址

app.MapSignalR("/signalr", new HubConfiguration());

这里修改后,客户端也要做相应的改变

$.connection.hub.url = "/signalr"
$.connection.hub.start().done(init);
var connection = $.hubConnection("/signalr", { useDefaultPath: false });

第三步:创建 Hub

using System.Threading;
using Microsoft.AspNet.SignalR;

namespace RealtimeNotifier
{
    public class RealtimeNotifierHub : Hub
    {
        public int recordsToBeProcessed = 100000;

        public void DoLongOperation(int num)
        {
            for (int record = 0; record <= recordsToBeProcessed; record++)
            {
                if (ShouldNotifyClient(record))
                {
                    if ( num==1) {
                        Clients.Caller.sendMessage(string.Format("成功!"));
                    }
                    if (num == 2) {

                        Clients.Caller.sendMessage(string.Format("发送--{0}!",record));
                    }
                    
                    Thread.Sleep(10);
                }
            }
        }

        private static bool ShouldNotifyClient(int record)
        {
            return record % 10 == 0;
        }
    }
}

RealtimeNotifierHub 中,DoLongOperation 模拟一个很耗时的方法,客户端可以通过调用这个方法,获取最后的执行结果。

Hub 在客户端生成代理

 var realtimeNotifier = $.connection.realtimeNotifierHub;

可以通过 HubNameAttribute修改客户端代理的名称

//Server

[HubName("NotifierHub")]
public class RealtimeNotifierHub : Hub

//JavaScript client 

var NotifierHubbProxy = $.connection.NotifierHub;

注意点如何选择客户端 PRC 通道

  • 面向所有客户端
Clients.All.sendMessage(msg);
  • 面向请求客户端
  Clients.Caller.sendMessage(string.Format("成功!"));
  • 面向指定客户端
Clients.Client(Context.ConnectionId).sendMessage(msg);

除此之外还有面向特定组,特定用户名等。

第四步:Web 客户端



    Real-time notifier
    
    
    
    


    

通过以上四步实现了,一个服务端耗时任务执行完后对客户端即时通知。

参考资料

http://www.asp.net/signalr/overview/getting-started

http://www.codeproject.com/Tips/672433/Real-time-Notifications-with-SignalR

感谢 GustavoMartins 文中例子是在他文章基础上的修改。

你可能感兴趣的:(通过 SignalR 实现耗时任务实时通知)