65.9K
CodeProject 正在变化。 阅读更多。
Home

集成 WCF 和 HTML5 来监控系统资源

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (13投票s)

2013 年 6 月 4 日

CPOL

4分钟阅读

viewsIcon

34867

downloadIcon

1053

监控系统的整体架构。

介绍  

本文介绍了如何集成 Microsoft .NET 技术和最新的 Web 工具(如 HTML5、jQuery 和 Flot)来监控和展示系统资源数据(例如 CPU 使用率和内存负载)。

所提供的解决方案可以作为扩展应用程序的骨架,用于管理和监控远程设备。下图是基于 WCF 服务的整体架构:每个远程设备公开一个由 Windows 服务托管的 WCF 服务,所有来自远程设备的信息由 IIS 托管的 Web 应用程序收集并公开。

 

以下的实现仅监控一台设备(即 Web 服务器 IIS 所在的同一台设备),但只需添加几行代码即可轻松扩展到监控多台设备。用于检索系统资源使用情况的代码基于我编写的一个 C++ COM 对象,并在此提供为 DLL 文件。

背景 

提供的代码打包在 Visual Studio 2012 解决方案中,包含 Windows 服务项目和 Web 应用程序项目。需要具备 WCF、jQuery 和 HTML5 的基础知识。此外,主网页使用了 Flot,一个用于 jQuery 的 JavaScript 图表库(更多信息请参阅 http://www.flotcharts.org/)。

主要内容是关于 WCF 服务的配置,Web 中的 Ajax 支持以及 Windows 服务中的 wsHttpBinding。要使用 COM 对象 SystemManager 提供的服务,只需在您要监控的机器上注册LogthetaSystemManagement.dll(请参阅上方)。

设置解决方案并运行代码

“SystemMonitor”解决方案包含两个项目:

  • SystemManagementService:一个托管 WCF 服务并收集机器数据(CPU 使用率和内存负载)的 Windows 服务。
  • SystemMonitor.WebUI:一个 Web UI,托管一个 WCF 服务,该服务轮询安装在远程设备(在此示例中,与 Web 服务器在同一台机器上)上的 Windows 服务的数据,并在网页上绘制图表。

 

要编译并运行解决方案,请按照以下步骤操作:

  • 注册 SystemManagementService 项目中包含的Logtheta.SystemManagement.dll COM 组件:打开 Shell 并运行 regsvr32 [Path]\Logtheta.SystemManagement.dll。之后,您应该能在 dcomcnfg 中看到该组件。
  • 全部重新生成
  • 运行 SystemManagementService 项目中包含的 InstallService.cmd 文件来安装 Windows 服务。此批处理文件会安装并启动服务。之后,您将有一个 HTTP WCF 服务响应在App.config中配置的 URL。
  • 将 SystemMonitor.WebUI 注册为 Web 应用程序(属性 > Web > 创建虚拟目录)。
  • 运行解决方案

使用代码 

public class SystemManagementService : ISystemManagementService
{
    /// <summary>
    /// Retrieve CPU usages
    /// </summary>
    /// <returns></returns>
    public double GetCPUUsages()
    {
        ISystemManager systemManager = new SystemManager();
        return systemManager.GetCPUUsages();
    }
    /// <summary>
    /// Retrieve System Memory usage
    /// </summary>
    /// <returns></returns>
    public double GetMemoryUsage()
    {
        ISystemManager systemManager = new SystemManager();
        uint availableMemory =  systemManager.GetAvailableRAM();
        uint totalMemory = systemManager.GetTotalRAM();
        return (1 - ((double)availableMemory) / totalMemory) * 100;
    } 
}

此代码使用Logtheta.SystemManagement.dll中的SystemManger互操作类来检索 CPU 使用率和内存使用率。

该服务封装在一个 Windows 服务应用程序中,以避免在远程设备上安装 IIS。

您可以通过更改App.config中指定的“baseAddress”来更改 WCF 服务响应的端口:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <system.serviceModel>
    <services>
      <service name="Logtheta.SystemManagementService">
        <host>
          <baseAddresses>
            <add baseAddress="https://:8000/LogthetaServices/SystemManagementService"/>
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host: 
              https://:8000/LogthetaServices/SystemManagementService  -->
        <endpoint address="" binding="wsHttpBinding" 
              contract="Logtheta.ISystemManagementService"/>
        <!-- the mex endpoint is exposed at 
          https://:8000/LogthetaServices/SystemManagementService/mex -->
        <endpoint address="mex" binding="mexHttpBinding" 
               contract="IMetadataExchange"/>
      </service>
    </services>
    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration> 

请注意,该服务使用的是 wsHttpBinding。

一旦远程设备上的 Windows 服务启动并运行,您就可以从 Web 应用程序进行连接。在web.config中,您可以找到 WCF 客户端定义:

<client>
    <endpoint address="https://:8000/LogthetaServices/SystemManagementService"
          binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ISystemManagementService"
          contract="SystemManagementService.ISystemManagementService"
          name="SystemManagementService">
     <identity>
            <servicePrincipalName value="host/VaioGiuseppe" />
     </identity>
    </endpoint>
</client>  

如果需要,请进行更改。为了展示数据,我们需要一个启用了 WCF 服务 Ajax,以便我们可以使用 jQuery 以 JSON 格式检索数据:

[ServiceBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = 
        AspNetCompatibilityRequirementsMode.Allowed)]
public class SystemMonitorService : ISystemMonitorService
{
   [WebGet(ResponseFormat = WebMessageFormat.Json)]
   public SystemResources GetSystemResources()
   {
        //@TODO: change this in order to retrieve the uri from
        //DB if you want to manage mul	tiple systems monitor
        Uri endPointUri = 
          new Uri("https://:8000/LogthetaServices/SystemManagementService");
        SystemManagementServiceClient systemManagementService = 
          GetSystemManagementServiceClient(endPointUri);
        double cpuUsages = systemManagementService.GetCPUUsages();
        double memoryUsage = systemManagementService.GetMemoryUsage();
        return new SystemResources { CPUUsages = cpuUsages, 
          MemoryUsage = memoryUsage , Hostname = "localhost"};
   }

   private SystemManagementServiceClient GetSystemManagementServiceClient(Uri endPointUri)
   {
      Binding binding = new WSHttpBinding();
      EndpointAddress endpoint = new EndpointAddress(endPointUri);
      SystemManagementServiceClient client = new SystemManagementServiceClient(binding, endpoint);
      return client;
   }
} 

请注意,主方法“GestSystemResources”已装饰,以便使用 JSON 格式。如果您对远程 WCF 服务配置进行了任何更改,则需要相应地更改 endPoiuntUri 变量。

现在我们可以使用 AJAX 调用已启用 Ajax 的 WCF 服务。Web 应用程序“Scripts”文件夹中的app.js文件包含了检索数据、设置 Flot 控件和定期绘制数据的所有代码。App.js中的主要代码是:

function getData() {
     $.ajax({
        type: "GET",
        url: serviceUrl,
        cache: false,
        data: {},
        contentType: "application/json; charset=utf-8",
        dataType: "text",
        success: OnSuccess,
        error: OnError
      });

      function OnSuccess(response) {
        //console.log("OnSuccess data");
        var s = JSON.parse(response);
                
        //draw cpu and memory data
        cpuPlot.setData([cpuPlotData.buildData(s.d.CPUUsages)]);
        cpuPlot.draw();
        memPlot.setData([memPlotData.buildData(s.d.MemoryUsage)]);
        memPlot.draw();
        setTimeout(updateStatistics, updateInterval);
      }

      function OnError(response) {
          var r = JSON.parse(response);
          alert("Error");
         }
  }; 

请注意,AJAX 调用中的 dataType 必须是“text”,这样您才能在“OnSuccess”回调中通过 JSON.parse 方法解析结果。

值得关注的点  

您可以扩展此解决方案来监控多台设备,只需添加一个简单的 SQL Server 数据库和 Entity Framework 来访问数据。您始终需要在远程机器上安装 Windows 服务,但即使未安装 IIS,您也可以通过 HTTP 检索数据。

历史

  • 2013 年 6 月 4 日:首次发布。
© . All rights reserved.