zoukankan      html  css  js  c++  java
  • 如何使用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

  • 相关阅读:
    SQLSERVER的非聚集索引结构
    SQLSERVER编译与重编译
    SQL Server读懂语句运行的统计信息 SET STATISTICS TIME IO PROFILE ON
    查看SQLSERVER内部数据页面的小插件Internals Viewer(续)
    关于学习编程和做好DBA的关系
    SQLSERVER中得到执行计划的方式
    SQLSERVER的排序问题
    对《30个提高Web程序执行效率的好经验》的理解
    挂载非引用Assembly中的事件
    枚举的多语言显示
  • 原文地址:https://www.cnblogs.com/crosplion/p/6278315.html
Copyright © 2011-2022 走看看