通常来讲一个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服务运行状态的监测的更多相关文章

  1. SignalR实现B/S系统对windows服务运行状态的监测

    基于SignalR实现B/S系统对windows服务运行状态的监测 通常来讲一个BS项目肯定不止单独的一个BS应用,可能涉及到很多后台服务来支持BS的运行,特别是针对耗时较长的某些任务来说,Windo ...

  2. C++ 检查Windows服务运行状态

    检查Windows服务运行状态  C++ Code  1234567891011121314151617181920212223242526272829303132333435363738394041 ...

  3. C#曲线分析平台的制作(五,Sqldependency+Signalr+windows 服务 学习资料总结)

    在前篇博客中,利用interval()函数,进行ajax轮询初步的实现的对数据的实时显示.但是在工业级别实时显示中,这并非是一种最好的解决方案.随着Html5 websocket的发展,这种全双工的通 ...

  4. Topshelf+Quartz3.0基于控制台应用程序快速开发可调度windows服务

    1.TopShelf TopShelf是一个开源的跨平台的宿主服务框架.可通过.Net Core/.Net Framwork控制台应用程序快速开发windows服务,更加便于服务调试. 本文基于.Ne ...

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

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

  6. C#曲线分析平台的制作(六,Sqldependency+Signalr+windows 服务)

    在经过五天的学习和资料收集后,终于初步实现了利用sqldependency进行数据库变化监控,signalr进行前后台交互,数据实时更新.下面将源代码贴出进行初步分析: 1.系统整体框架构成: 2.具 ...

  7. 连表查询都用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%我不知道在 ...

  8. asp.net基于windows服务实现定时发送邮件的方法

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

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

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

随机推荐

  1. 奇异值分解(SVD)原理与在降维中的应用

    奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...

  2. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  3. 为.NET Core项目定义Item Template

    作为这个星球上最强大的IDE,Visual Studio不仅仅提供了很多原生的特性,更重要的是它是一个可定制的IDE,比如自定义Project Template和Item Template就是一个非常 ...

  4. submit text3常用快捷键

    在网上找了一些submit text的快捷键: Ctrl+D 选词 (反复按快捷键,即可继续向下同时选中下一个相同的文本进行同时编辑)Ctrl+G 跳转到相应的行Ctrl+J 合并行(已选择需要合并的 ...

  5. C++随笔:.NET CoreCLR之GC探索(4)

    今天继续来 带大家讲解CoreCLR之GC,首先我们继续看这个GCSample,这篇文章是上一篇文章的继续,如果有不清楚的,还请翻到我写的上一篇随笔.下面我们继续: // Initialize fre ...

  6. C#泛型详解(转)

    初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...

  7. JQuery中的siblings()是什么意思

    jQuery siblings() 方法返回被选元素的所有同胞元素,并且可以使用可选参数来过滤对同胞元素的搜索. 实例演示:点击某个li标签后将其设置为红色,而其所有同胞元素去除红色样式. 1.创建H ...

  8. 一行代码实现java list去重

    1.不带类型写法: 1 List listWithoutDup = new ArrayList(new HashSet(listWithDup)); 2.带类型写法(以String类型为例):1)Ja ...

  9. 简单酷炫的canvas动画

    作为一个新人怀着激动而紧张的心情写了第一篇帖子还请大家多多支持,小弟在次拜谢. 驯鹿拉圣诞老人动画效果图如下 html如下: <div style="width:400px;heigh ...

  10. jira的插件开发流程实践

    怎么开头呢,由于自己比较懒,博客一直不怎么弄,以后克己一点,多传点自己遇到的问题和经历上来,供自己以后记忆,也供需要的小伙伴少走点弯路吧 最近公司项目需要竞标一个运维项目,甲方给予了既定的几种比较常用 ...