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

  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/crosplion/p/6278315.html
Copyright © 2011-2022 走看看