基于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秒钟推送一次
具体代码如下
using System.Linq;
using System.Threading; namespace wxRbt.Service.Realtime.Hub
{
/// <summary>
/// 服务监控器
/// </summary>
public class ServiceMonitorHub:Microsoft.AspNet.SignalR.Hub
{
static ServiceMonitorHub()
{
new Thread(new ThreadStart(() =>
{
while (true)
{
//获取所有服务名称以wxRbt开头的服务
var services = System.ServiceProcess.ServiceController.GetServices().Where(t => t.ServiceName.StartsWith("wxRbt"))
.Select(t => new Model.Service
{
DisplayName = t.DisplayName,
ServiceName = t.ServiceName,
Status = (int)t.Status
}).ToArray();
Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<ServiceMonitorHub>().Clients.All.refresh(services);
//休眠一秒,实现每秒推送服务运行状态
System.Threading.Thread.Sleep();
}
})).Start();
}
}
}
现在我们再利用TopShelf把当前的控制台安装成windows服务
新建一个类ServiceMonitorService,继承Topshelf.ServiceControl接口,实现其Start跟Stop方法,具体代码如下
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using System;
using Topshelf;
using System.Configuration; namespace wxRbt.Service.Realtime.Service
{
public class ServiceMonitorService:ServiceControl
{
private IDisposable app;
private static string domain="http://*:3333"; 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;
}
}
}
这里给个默认的监听域名,然后从app.config读取配置的监听域名
最后打开Progarm.cs文件,代码如下:
using Topshelf; namespace wxRbt.Service.Realtime
{
class Program
{
static void Main(string[] args)
{
HostFactory.Run(s => {
s.Service<Service.ServiceMonitorService>();
s.SetDisplayName("微信实时消息服务");
s.StartAutomatically();
});
}
}
}
调试运行程序,如图

上面服务端已经完成,下面,我们来实现客户端:
创建一个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写一个消息模块
/// <reference path="../../../scripts/typings/signalr/signalr.d.ts" />
module wxrbt.manager {
export const enum ServiceStatus {
/**服务停止*/
Stopped = ,
/**正在运行*/
StartPending = ,
/**正在停止*/
StopPending = ,
/**运行中*/
Running = ,
/**正在继续*/
ContinuePending = ,
/**正在暂停*/
PausePending = ,
/**已暂停*/
Paused = ,
}
interface IService {
DisplayName: string;
ServiceName: string;
Status: ServiceStatus
}
/**管理服务*/
export class service {
private proxy: SignalR.Hub.Proxy;
private $: JQueryStatic;
private ip: string;
private port: number;
constructor(ip: string, port: number) {
this.ip = ip;
this.port = port;
}
/**
* 开启服务运行状态监测
* @param {(services} callback
*/
start(callback: (services: Array<IService>) => void) {
jQuery.getScript("http://" + this.ip + ":" + this.port + "/signalr/hubs", () => {
jQuery.connection.hub.url = "http://" + this.ip + ":" + this.port + "/signalr";
this.proxy = jQuery.signalR.hub.createHubProxy("ServiceMonitorHub");
//每次刷新数据回调
this.proxy.on("refresh", (services: Array<IService>) => {
callback(services);
});
jQuery.connection.hub.start().fail(() => {
alert("连接实时消息服务期:http://" + this.ip + ":" + this.port + "失败,请确认消息服务配置正确且正常开启!");
});
});
}
}
}
下面我结合RequireJs实现的该模块调用
require(["message"], () => {
jQuery(() => {
var $service = jQuery("#serviceList");
var msg = new wxrbt.manager.service("127.0.0.1", 3333);
msg.start(services=>{
$service.empty();
for (let service of services) {
var isRunning = service.Status == wxrbt.manager.ServiceStatus.Running;
var statusCls = isRunning ? "success" : "warning";
var statusTxt = isRunning ? "运行中" : "已停止";
var status = `<label class='label label-${statusCls}'>${statusTxt}</label>`;
$service.append(`<li><a href='javascript:;'><i class='icon-check'></i>${service.DisplayName}${status}</a></li><li class="divider"></li>`);
}
});
});
});
最后运行页面查看效果:

唯一不足的就是1秒钟这个dropdownlist会闪动一次,我这里是先清除再append进来,所以会出现这个情况,如果采用dom节点递归更新状态就不会有这个问题了!
因为是公司项目,没办法上源码!有不清除的可以留言!
下面是在windows服务器上跑的服务截图

基于SignalR实现B/S系统对windows服务运行状态的监测的更多相关文章
- SignalR实现B/S系统对windows服务运行状态的监测
基于SignalR实现B/S系统对windows服务运行状态的监测 通常来讲一个BS项目肯定不止单独的一个BS应用,可能涉及到很多后台服务来支持BS的运行,特别是针对耗时较长的某些任务来说,Windo ...
- C++ 检查Windows服务运行状态
检查Windows服务运行状态 C++ Code 1234567891011121314151617181920212223242526272829303132333435363738394041 ...
- C#曲线分析平台的制作(五,Sqldependency+Signalr+windows 服务 学习资料总结)
在前篇博客中,利用interval()函数,进行ajax轮询初步的实现的对数据的实时显示.但是在工业级别实时显示中,这并非是一种最好的解决方案.随着Html5 websocket的发展,这种全双工的通 ...
- Topshelf+Quartz3.0基于控制台应用程序快速开发可调度windows服务
1.TopShelf TopShelf是一个开源的跨平台的宿主服务框架.可通过.Net Core/.Net Framwork控制台应用程序快速开发windows服务,更加便于服务调试. 本文基于.Ne ...
- windows服务,安装、启动、停止,配置,一个批处理文件搞定
相对而言,还是比较通用的吧,如果哪位仁兄有更好的实现方式,或者发现有不足之处,还请多多指教. @echo off echo.------------------------------------- ...
- C#曲线分析平台的制作(六,Sqldependency+Signalr+windows 服务)
在经过五天的学习和资料收集后,终于初步实现了利用sqldependency进行数据库变化监控,signalr进行前后台交互,数据实时更新.下面将源代码贴出进行初步分析: 1.系统整体框架构成: 2.具 ...
- 连表查询都用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%我不知道在 ...
- asp.net基于windows服务实现定时发送邮件的方法
本文实例讲述了asp.net基于windows服务实现定时发送邮件的方法.分享给大家供大家参考,具体如下: //定义组件 private System.Timers.Timer time; publi ...
- C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
随机推荐
- 【.net 深呼吸】细说CodeDom(7):索引器
在开始正题之前,先补充一点前面的内容. 在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参 ...
- 关于自己写C++的一点风格
现在,我学了很长时间的C++,但是自己就是无法精通.许多知识是入门书上没有的.现在写C++最重要的就是风格问题. 我现在的C++风格: 把自己所有的东西都放在一个名称空间下. 没有全局的函数,有的函数 ...
- 你真的会玩SQL吗?之逻辑查询处理阶段
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 2Sum
用哈希表(unordered_map)使得时间复杂度从O(n*n)降到O(n),空间复杂度从O(1)增到O(n):一边找一边插入哈希表 注意 在C++11以前要使用unordered_map需要 #i ...
- C#语法糖大汇总
首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...
- JavaScript将字符串中的每一个单词的第一个字母变为大写其余均为小写
要求: 确保字符串的每个单词首字母都大写,其余部分小写. 这里我自己写了两种方法,或者说是一种方法,另一个是该方法的变种. 第一种: function titleCase(str) { var new ...
- mysql开启慢查询日志及查询--windows
MySQL慢查询配置 1. 慢查询有什么用? 它能记录下所有执行超过long_query_time时间的SQL语句, 帮你找到执行慢的SQL, 方便我们对这些SQL进行优化. 2. 如何开启慢查询? ...
- CentOS:设置系统级代理(转)
原文地址:http://www.cnblogs.com/cocowool/archive/2012/07/05/2578487.html YUM代理设置 编辑/etc/yum.conf,在最后加入 # ...
- ENode 2.8 最新架构图简介
ENode架构图 什么是ENode ENode是一个.NET平台下,纯C#开发的,基于DDD,CQRS,ES,EDA,In-Memory架构风格的,可以帮助开发者开发高并发.高吞吐.可伸缩.可扩展的应 ...
- Java:Double Brace Initialization
在我刚刚接触现在这个产品的时候,我就在我们的代码中接触到了对Double Brace Initialization的使用.那段代码用来初始化一个集合: final Set<String> ...