SignalR实现B/S系统对windows服务运行状态的监测
基于SignalR实现B/S系统对windows服务运行状态的监测
通常来讲一个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.Hub
5 {
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.Realtime
5 {
6 class Program
7 {
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服务器上跑的服务截图

SignalR实现B/S系统对windows服务运行状态的监测的更多相关文章
- 基于SignalR实现B/S系统对windows服务运行状态的监测
通常来讲一个BS项目肯定不止单独的一个BS应用,可能涉及到很多后台服务来支持BS的运行,特别是针对耗时较长的某些任务来说,Windows服务肯定是必不可少的,我们还需要利用B/S与windows服务进 ...
- C++ 检查Windows服务运行状态
检查Windows服务运行状态 C++ Code 1234567891011121314151617181920212223242526272829303132333435363738394041 ...
- C#曲线分析平台的制作(五,Sqldependency+Signalr+windows 服务 学习资料总结)
在前篇博客中,利用interval()函数,进行ajax轮询初步的实现的对数据的实时显示.但是在工业级别实时显示中,这并非是一种最好的解决方案.随着Html5 websocket的发展,这种全双工的通 ...
- windows服务,安装、启动、停止,配置,一个批处理文件搞定
相对而言,还是比较通用的吧,如果哪位仁兄有更好的实现方式,或者发现有不足之处,还请多多指教. @echo off echo.------------------------------------- ...
- 连表查询都用Left Join吧 以Windows服务方式运行.NET Core程序 HTTP和HTTPS的区别 ASP.NET SignalR介绍 asp.net—WebApi跨域 asp.net—自定义轻量级ORM C#之23中设计模式
连表查询都用Left Join吧 最近看同事的代码,SQL连表查询的时候很多时候用的是Inner Join,而我觉得对我们的业务而言,99.9%都应该使用Left Join(还有0.1%我不知道在 ...
- C#曲线分析平台的制作(六,Sqldependency+Signalr+windows 服务)
在经过五天的学习和资料收集后,终于初步实现了利用sqldependency进行数据库变化监控,signalr进行前后台交互,数据实时更新.下面将源代码贴出进行初步分析: 1.系统整体框架构成: 2.具 ...
- Windows服务二:测试新建的服务、调试Windows服务
一.测试Windows服务 为了使Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点.像其他应用程序一样,Windows服务也是在Program.cs的Main ...
- 通过SSIS监控远程服务器Windows服务并发送邮件报警!
利用SSIS不仅可以做BI项目的ETL,而且还可以做一些系统监控和维护工作,由于之前供应商写的Windows服务是读取ESB的消息进行处理,且通过OA流程与访客系统进行了集成,无论是ESB出现状况,还 ...
- Windows服务的手动添加和删除方法
Windows服务的手动添加和删除方法 服务,是指执行指定系统功能的程序.例程或进程,以便支持其他程序,尤其是低层(接近硬件)程序.其实,服务就是一种特殊的应用程序,它从服务启动开始就一直处于运行状态 ...
随机推荐
- 在world2013中插入GB_2312
文字添加方法: 1.下载字体并解压 2.开始中打开控制面板 3.在控制面板中打开字体文件夹 4.把下载的字体复制到此文件下 5.文字添加完成.
- fastjson 的简单说明及使用
fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发. 各个版本jar包下载地址:https://repo1.maven.org/maven2/ ...
- TPL中的task并不是thread
Tasks are not Threads - The Brain Dump用了一个非常简单直观的例子说明了task和thread并不是一回事(尽管你调用Task.Run一般会在线程池上启一个线程帮你 ...
- 20169210《Linux内核原理与分析》第三周作业
本次作业也是分为两部分,第一部分是对实验楼<Linux基础入门>复习,第二部分为对课本18章的复习. 第一次学习实验楼的<Linux基础入门>时由于是第一次接触Linux,所以 ...
- (转)PHP连接数据库之PHP连接MYSQL数据库代码
PHP连接数据库之PHP连接MYSQL数据库代码 < ?php $mysql_server_name='localhost'; //改成自己的mysql数据库服务器 $mysql_usernam ...
- UML类图详细介绍
类图主要描述程序对象以及他们之间的关系.一般来说,类.接口.抽象类这些程序对象的区别很容易,但是他们之间六种关系以前总是理解不够深刻,这次进行了一次复习,顺便写成博文以便加深理解 类图中的三种对象 类 ...
- [Oracle] Data Pump 详细使用教程(4)- network_link
[Oracle] Data Pump 详细使用教程(1)- 总览 [Oracle] Data Pump 详细使用教程(2)- 总览 [Oracle] Data Pump 详细使用教程(3)- 总览 [ ...
- php 总结
1.安装完apache之后 2.有一个目录 htdocs 下面就是根目录了 3.测试一下,新建一个index.html 写入 it works .输入localhost 看是否显示 it works ...
- htmlentities() 函数
Definition and Usage定义和用法 The htmlentities() function converts characters to HTML entities.htmlentit ...
- "_Default"同时存在于两个dll文件中的解决办法
编译器错误消息:CS0433: 类型“_Default”同时存在于“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Fi ...