如何使用SignaIR实现实时信息推送到客户端

  最近在做和以前同学做一个接的网站,因为有个需求,就是需要在某个数据库表里面插入一条信息的时候,我们需要把这条消息推送给所有的订阅这条消息的用户知道,我因为原来没有做过有关服务器主动消息推送的项目(PS:最初毕业那会是直接用ajax不断定时去获取数据库里面的记录来更新客户端的UI), 所以瞬间有点泪奔的感觉, 不过总是要硬着头皮上的哇,一头雾水,开始在网上一顿搜,网上倒是有不少解决方案, 例如使用Html的websocket协议直接开干,不过用户那边的浏览器不同意,可能不大适应直接这样做的节奏. 因为以前在微软做过小小的技术support, 所以自己还是想起来重拾SignaIR, 我的思路就是每次在在新增信息模块将消息存入一个队列,我自己在后台运行一个windows service, 每个固定时间去消息队列里面去获取最新插入的记录实体对象,如果有记录,那么我们通过Hub去推送到客户端,然后清除这个消息。这里的代码真的要感谢 汤国臣,我的大部分基本受这位大神的启发, 后面我会贴上相关的这位大神的链接参考. 废话不多说,进入正题。我不喜欢说太多,凡事都是例子为主吧, 写了个小例子. 源代码要的哈告诉我.

  首先创建一个控制台应用程序,Nuget添加 Microsoft.AspNet.SignalR.SelfHost Microsoft.Owin.Cors TopShelf(实现windows服务安装),新建一个hub命名为ServiceMonitorHub,继承Microsoft.AspNet.SignalR.Hub,我们要实现服务状态3秒钟推送一次. 其实我自己项目里面是自己监测消息队列里面有没有最新的记录,如果有取出来推送,但是考虑到实际的每个人的需求不一样,这里我就每隔三秒钟去推送一次.

using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RealtimeService
{
    /// <summary>
    /// 服务监控器
    /// </summary>
    public  class ServiceMonitorHub : Hub
    {
        static ServiceMonitorHub()
        {
            new Thread(new ThreadStart(() =>
            {
                while (true)
                {
                    GlobalHost.ConnectionManager.GetHubContext<ServiceMonitorHub>().Clients.All.sendMessage(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Kelin zhang");
                    //休眠3秒,实现每秒推送服务运行状态
                    System.Threading.Thread.Sleep(3000);
                }
            })).Start();
        }
    }
}

新建一个类ServiceMonitorService,继承Topshelf.ServiceControl接口,实现其Start跟Stop方法,具体代码如下:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;
using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Hosting;
using Microsoft.Owin.Host.HttpListener;
using Microsoft.Owin.Cors;
using Microsoft.AspNet.SignalR;

namespace RealtimeService
{
    public class ServiceMonitorService : ServiceControl
    {
        private IDisposable app;

        private static string domain = "http://192.168.10.89:3333"; //你自己的IP地址服务

        static ServiceMonitorService()
        {
            domain = ConfigurationManager.AppSettings["Domain"] ?? domain;
            Console.WriteLine("获取配置:" + domain);
        }

        public bool Start(HostControl hostControl)
        {
            Console.WriteLine("事实消息服务运行在:" + domain);

            app = WebApp.Start(domain, builder =>
            {
                builder.UseCors(CorsOptions.AllowAll);
                builder.MapSignalR(new HubConfiguration
                {
                    EnableJSONP = true,
                    EnableDetailedErrors = true,
                    EnableJavaScriptProxies = true
                });
            });
            return true;
        }

        public bool Stop(HostControl hostControl)
        {
            if (app != null)
            {
                app.Dispose();
            }
            return true;
        }
    }
}

最后打开Progarm.cs文件,代码如下:

using System;
using Topshelf;

namespace RealtimeService
{
    class Program
    {
        static void Main(string[] args)
        {
            HostFactory.Run(s => {
                s.Service<ServiceMonitorService>();
                s.SetDisplayName("实时消息服务");
                s.StartAutomatically();
            });

            Console.ReadKey();
        }
    }
}

然后我们直接运行这个控制台程序,就可以看到如下页面:

为了注册这个服务到系统里面, 用管理员权限打开cmd, 然后进行注册吧! 如果你不会,可以参考下面的链接:

http://www.cnblogs.com/jys509/p/4614975.html

基本上服务端就这样Happy的完成了, 我们开启这个服务,然后呢我们新建一个空的MVC的web项目.在Home控制器里面的Index的cshtml里面加上下面的代码:

@{
    ViewBag.title = "SignaIR";
}
<div class="container">
    <ul id="messageBox"></ul>
</div>
@section scripts
    {
    <script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>
    <script src="http://192.168.10.89:3333/signalr/hubs"></script>
    <script>

        $(function () {

            $.connection.hub.url = "http://192.168.10.89:3333/signalr";
            //引用自动生成的集线器代理
            var chat = $.signalR.hub.createHubProxy("ServiceMonitorHub");

             //    var chat = $.connection.ServiceMonitorHub;
                 //定义服务器调用的客户端sendMessage来显示新消息
                chat.client.sendMessage = function (name, message)
                {
                    //向页面添加消息
                    $("#messageBox").append('<li><strong style="color:green">'+htmlEncode(name)+'</strong>:'+htmlEncode(message)+'</li>');
                }

                //开始连接服务器
                $.connection.hub.start().done(function () {

                })
            });
            //为显示的消息进行html编码
            function htmlEncode(value)
            {
                var encodeValue = $('<div/>').text(value).html();
                return encodeValue;
            }
    </script>
}  

运行吧骚年,最终你就可以Happy的看看效果图了.

 希望对大家有点帮助,在做服务端消息推送的时候.

最后附上我这次搞这个功能设计参考的引用资料,智慧来自他们.

http://www.cnblogs.com/soundcode/p/5888250.html

https://www.asp.net/signalr

原文地址:https://www.cnblogs.com/crosplion/p/6278315.html