通常来讲一个BS项目肯定不止单独的一个BS应用,可能涉及到很多后台服务来支持BS的运行,特别是针对耗时较长的某些任务来说,Windows服务肯定是必不可少的,我们还需要利用B/S与windows服务进行交互,来实现更好的用户体验,搭配redis,memcached等来实现分布式缓存,消息列队处理等等。。。

但是通常情况我们在B/S端是无法得知其依赖的windows服务当前处于什么样的运行状态,只能通过到server里面去进行查看,或者通过其他途径!

今天我们就通过SignalR来实现一个B/S端对windows服务运行状态的监控,这里我们用SignalR selfHost,不依赖IIS,然后利用topshelf把SignalR Server部署成windows服务,然后在B/S端通过SignalR js client进行连接获取服务运行状态!

首先创建一个控制台应用程序,.NET 4.5,Nuget添加 Microsoft.AspNet.SignalR.SelfHost Microsoft.Owin.Cors TopShelf(实现windows服务安装)

具体新建SignalR SelfHost Server的方法可以看我以前的博客:SignalR SelfHost实时消息,集成到web中,实现服务器消息推送

新建一个hub命名为ServiceMonitorHub,继承Microsoft.AspNet.SignalR.Hub,我们要实现服务状态1秒钟推送一次

具体代码如下

 1 using System.Linq;2 using System.Threading;3 4 namespace wxRbt.Service.Realtime.Hub5 {6     /// <summary>7     /// 服务监控器8     /// </summary>9     public class ServiceMonitorHub:Microsoft.AspNet.SignalR.Hub
10     {
11         static ServiceMonitorHub()
12         {
13             new Thread(new ThreadStart(() =>
14             {
15                 while (true)
16                 {
17                     //获取所有服务名称以wxRbt开头的服务
18                     var services = System.ServiceProcess.ServiceController.GetServices().Where(t => t.ServiceName.StartsWith("wxRbt"))
19                         .Select(t => new Model.Service
20                         {
21                             DisplayName = t.DisplayName,
22                             ServiceName = t.ServiceName,
23                             Status = (int)t.Status
24                         }).ToArray();
25                     Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<ServiceMonitorHub>().Clients.All.refresh(services);
26                     //休眠一秒,实现每秒推送服务运行状态
27                     System.Threading.Thread.Sleep(1000);
28                 }
29             })).Start();
30         }
31     }
32 }

现在我们再利用TopShelf把当前的控制台安装成windows服务

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

 1 using Microsoft.AspNet.SignalR;2 using Microsoft.Owin.Cors;3 using Microsoft.Owin.Hosting;4 using Owin;5 using System;6 using Topshelf;7 using System.Configuration;8 9 namespace wxRbt.Service.Realtime.Service
10 {
11     public class ServiceMonitorService:ServiceControl
12     {
13         private IDisposable app;
14         private static string domain="http://*:3333";
15
16         static ServiceMonitorService() {
17             domain = ConfigurationManager.AppSettings["Domain"] ?? domain;
18             Console.WriteLine("获取配置:"+domain);
19         }
20
21         public bool Start(HostControl hostControl)
22         {
23             Console.WriteLine("事实消息服务运行在:"+domain);
24
25             app = WebApp.Start(domain, builder =>
26             {
27                 builder.UseCors(CorsOptions.AllowAll);
28                 builder.MapSignalR(new HubConfiguration
29                 {
30                     EnableJSONP = true,
31                     EnableDetailedErrors = true,
32                     EnableJavaScriptProxies = true
33                 });
34             });
35             return true;
36         }
37
38         public bool Stop(HostControl hostControl)
39         {
40             if (app != null) {
41                 app.Dispose();
42             }
43             return true;
44         }
45     }
46 }

这里给个默认的监听域名,然后从app.config读取配置的监听域名

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

 1 using Topshelf;2 3 4 namespace wxRbt.Service.Realtime5 {6     class Program7     {8         static void Main(string[] args)9         {
10             HostFactory.Run(s => {
11                 s.Service<Service.ServiceMonitorService>();
12                 s.SetDisplayName("微信实时消息服务");
13                 s.StartAutomatically();
14             });
15         }
16     }
17 }

调试运行程序,如图

上面服务端已经完成,下面,我们来实现客户端:

创建一个MVC4.0web空项目(随便,个人爱好),Nuget引用Microsoft.AspNet.SignalR.JS,该js依赖jquery,会自动下载jquery,写TypeScript同学可以顺带下载这两个JS的d.ts文件

然后创建一个HomeController,在Index里面返回view即可

Views文件夹创建Home文件夹,创建一个Index.cshtml 的razor试图,引用jquery跟signalrjs

然后创建一个单独的JS,尽量不要把js写到页面里面去

这里我用TypeScript写一个消息模块

 1 /// <reference path="../../../scripts/typings/signalr/signalr.d.ts" />2 3 module wxrbt.manager {4     export const enum ServiceStatus {5         /**服务停止*/6         Stopped = 1,7         /**正在运行*/8         StartPending = 2,9         /**正在停止*/
10         StopPending = 3,
11         /**运行中*/
12         Running = 4,
13         /**正在继续*/
14         ContinuePending = 5,
15         /**正在暂停*/
16         PausePending = 6,
17         /**已暂停*/
18         Paused = 7,
19     }
20     interface IService {
21         DisplayName: string;
22         ServiceName: string;
23         Status: ServiceStatus
24     }
25     /**管理服务*/
26     export class service {
27         private proxy: SignalR.Hub.Proxy;
28         private $: JQueryStatic;
29         private ip: string;
30         private port: number;
31         constructor(ip: string, port: number) {
32             this.ip = ip;
33             this.port = port;
34         }
35         /**
36          * 开启服务运行状态监测
37          * @param {(services} callback
38          */
39         start(callback: (services: Array<IService>) => void) {
40             jQuery.getScript("http://" + this.ip + ":" + this.port + "/signalr/hubs", () => {
41                 jQuery.connection.hub.url = "http://" + this.ip + ":" + this.port + "/signalr";
42                 this.proxy = jQuery.signalR.hub.createHubProxy("ServiceMonitorHub");
43
44                 //每次刷新数据回调
45                 this.proxy.on("refresh", (services: Array<IService>) => {
46                     callback(services);
47                 });
48
49
50                 jQuery.connection.hub.start().fail(() => {
51                     alert("连接实时消息服务期:http://" + this.ip + ":" + this.port + "失败,请确认消息服务配置正确且正常开启!");
52                 });
53             });
54         }
55     }
56 }

下面我结合RequireJs实现的该模块调用

 1 require(["message"], () => {2 3     jQuery(() => {4 5         var $service = jQuery("#serviceList");6         var msg = new wxrbt.manager.service("127.0.0.1", 3333);7         msg.start(services=>{8             $service.empty();9             for (let service of services) {
10                 var isRunning = service.Status == wxrbt.manager.ServiceStatus.Running;
11                 var statusCls = isRunning ? "success" : "warning";
12                 var statusTxt = isRunning ? "运行中" : "已停止";
13                 var status = `<label class='label label-${statusCls}'>${statusTxt}</label>`;
14                 $service.append(`<li><a href='javascript:;'><i class='icon-check'></i>${service.DisplayName}${status}</a></li><li class="divider"></li>`);
15             }
16         });
17
18     });
19
20
21 });

最后运行页面查看效果:

唯一不足的就是1秒钟这个dropdownlist会闪动一次,我这里是先清除再append进来,所以会出现这个情况,如果采用dom节点递归更新状态就不会有这个问题了!

因为是公司项目,没办法上源码!有不清除的可以留言!

下面是在windows服务器上跑的服务截图

http://www.cnblogs.com/263613093/p/5887636.html

基于SignalR实现B/S系统对windows服务运行状态的监测相关推荐

  1. windows服务,安装、启动、停止,配置,一个批处理文件搞定

    相对而言,还是比较通用的吧,如果哪位仁兄有更好的实现方式,或者发现有不足之处,还请多多指教.  @echo off echo.------------------------------------- ...

  2. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

    C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案 参考文章: (1)C#/.NET基于Topshelf创建Windows ...

  3. SignalR与自托管Windows服务

    目录 介绍 创建服务器 创建JavaScript客户端 服务器广播功能 创建StockTicker和StockTickerHub类 获取SignalR上下文,以便StockTicker类可以向客户端广 ...

  4. win服务器自动发邮件,asp.net基于windows服务实现定时发送邮件的方法

    本文实例讲述了asp.net基于windows服务实现定时发送邮件的方法.分享给大家供大家参考,具体如下: //定义组件 private System.Timers.Timer time; publi ...

  5. 第三节:Windows平台部署Asp.Net Core应用(基于IIS和Windows服务两种模式)

    一. 简介 Asp.Net Core 部署方式有两种:依赖框架和独立部署. 1. 框架依赖的部署: 顾名思义,依赖框架的部署 (FDD) 依赖目标系统上存在共享系统级版本的 .NET Core. 由于 ...

  6. 如何基于 dotnetcore worker service 创建 windows 服务

    .NET CORE 3.1 提供了 worker service 这么一个模板,可以方便开发者来创建"windows 服务程序"(同样可发布于 linux). 本篇以 centos ...

  7. ASP.NET Core项目基于Windows 服务的打包托管

    1. 工程创建 工程目标框架可为 .NetFramework 或 .NetCore,模板为 .NetCore下的API工程,正常编写工程代码即可 2.转换项目为Windows服务 修改工程的 .csp ...

  8. 更上层楼:动态安装你的windows服务

    前言:先说明一下本文示例windows服务的简单需求,即根据外部配置实现不同方式记录日志的功能.记录日志的方式有三种,分为文本记录.数据库记录以及文本和数据库同时记录日志.如您所知,这个功能基本上没有 ...

  9. windows 服务开发教程

    一. window服务是什么 当你单击"开始",执行"services.msc"命令.就会看见如下窗口.它显示的是当前操作系统中系统自带的服务或者第三方软件安装 ...

最新文章

  1. 华为存储iscsi配置_iscsi 华为存储配置 上课内容
  2. com口驱动_Ubuntu 安装Nvidia显卡驱动指南
  3. apicloud手机查看效果
  4. TP-Link路由器设置上网知识笔记
  5. LeetCode_database刷题记录(620. 有趣的电影)
  6. 从“No space left on device”到删除海量文件
  7. 分布式消息规范 OpenMessaging 1.0.0-preview 发布 1
  8. 深度学习基础(五)—— rectifier function and softplus
  9. 使用Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(一)
  10. Python数据处理Tips数据离群值的5种常用处理方法和可视化
  11. opencv转码,分辨率大小导致的bug
  12. 奖项公布|Sui Demo Day香港站获胜者名单新鲜出炉
  13. 【笔记】玩转CSS3新特性_from_JSPang
  14. JSP技术的发展趋势
  15. 可口可乐市场调查失败的原因_可口可乐公司的市场调查为什么没有起到预期效果?...
  16. BDE配置中的一个参数:SHAREDMEMLOCATION
  17. 一键获取主图设计模板的工具平台
  18. 2022 世界人工智能大会|人工智能与开源技术先锋论坛成功举办
  19. 相空间重构、时间序列重构、状态空间重构、phase space reconstruction、state space reconstruction
  20. 2020下半年信息系统监理师上午真题及答案

热门文章

  1. c++ vector方法
  2. QT的QLineSeries类的使用
  3. QT的QHash类的使用
  4. 13.5.虚拟化工具--jhat详解、13.6.虚拟化工具--jstack详解
  5. keras用cpu加速_在训练某些网络时,Keras(Tensorflow后端)在GPU上比在CPU上慢CPU
  6. python无法打开 firefox浏览器_【求助】pycharm不能打开火狐浏览器
  7. lotus表单域怎么获取视图结果_翻译案例 | 商业推广类文章怎么翻?如何修改译文?...
  8. jmeter constant timer 如何添加_阿里巴巴在开源压测工具 JMeter 上的实践和优化
  9. 鼠标动效html,5种纯CSS3鼠标hover按钮动画效果
  10. 钰群的USB3.0采集,可以实现哪些采集卡方案?