HTML5-WebSocket实现对服务器CPU实时监控

由于WebSocket允许保持长连接,因此当建立连接后服务器可以主动地向Client发送相关信息.下面通过服务端获取当前CPU的使用情况主动发送给网页,让网页实时显示CPU使用情况的曲线图.该事例的主要功能是包括服务端获取CPU使和情况和HTML5使用canvas进行曲线图绘制.

应用效果

实现效果主要是模仿windows的任务管理器,显示每个核的工作情况.

C#获取CPU使用情况

可能通过PerformanceCounter来获取具本CPU线程的使用情况,不过在构建PerformanceCounter前先获取到CPU对应的线程数量.获取这个数量可以通过Environment.ProcessorCount属性获取,然后遍历构建每个PerformanceCounter

?
1
2
3
4
5
int coreCount = Environment.ProcessorCount;        
             for ( int i = 0; i < coreCount; i++)
             {
                 mCounters.Add( new PerformanceCounter( "Processor" , "% Processor Time" , i.ToString()));
             }

为了方便计数器的处理,简单地封装了一个基础类,完整代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/// <summary>
     /// Copyright © henryfan 2012        
     ///Email:   henryfan@msn.com    
     ///HomePage:    http://www.ikende.com       
     ///CreateTime:  2012/12/24 15:10:44
     /// </summary>
     public class ProcessorCounter
     {
         private List<PerformanceCounter> mCounters = new List<PerformanceCounter>();
         public IList<PerformanceCounter> Counters
         {
             get
             {
                 return mCounters;
             }
         }
         public void Open()
         {
             int coreCount = Environment.ProcessorCount;        
             for ( int i = 0; i < coreCount; i++)
             {
                 mCounters.Add( new PerformanceCounter( "Processor" , "% Processor Time" , i.ToString()));
             }
         }
         public ItemUsage[] GetValues()
         {
             ItemUsage[] values = new ItemUsage[mCounters.Count];
             for ( int i = 0; i < mCounters.Count; i++)
             {
                 values[i] = new ItemUsage();
                 values[i].ID = i.ToString();
                 values[i].Name = "CPU " +i.ToString();
                 values[i].Percent =  mCounters[i].NextValue();
             }
             return values;
         }
     }
     public class ItemUsage
     {
         public string Name { get ; set ; }
         public float Percent { get ; set ; }
         public  string ID { get ; set ; }
     }

这样一个用于统计CPU所有线程使用情况计数的类就完成了.

页面绘制处理

首先定义一些简单的处理结构

?
1
2
3
4
5
6
7
8
9
10
11
function ProcessorInfo() {
             this .Item = null ;
             this .Points = new Array();
             for ( var i = 0; i < 50; i++) {
                 this .Points.push( new Point(0, 0));
             }
         }
         function Point(x, y) {
             this .X = x;
             this .Y = y;
         }

主要定义线程信息结构,默认初始化50个座标,当在接收服务线程使用情况的时候,构建一个点添加到数组件尾部同时把第一个移走.通过定时绘制这50个点的曲线这样一个动态的走势就可以完成了.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function drawProceessor(item) {
             var canvas = document.getElementById( 'processimg' + item.Item.ID);
             var context = canvas.getContext( '2d' );
             context.beginPath();
             context.rect(0, 0, 200, 110);
             context.fillStyle = 'black' ;
             context.fill();
             context.lineWidth = 2;
             context.strokeStyle = 'white' ;
             context.stroke();
             context.beginPath();
             context.moveTo(2, 106);
             for ( var i = 0; i < item.Points.length; i++) {
  
                 context.lineTo(4 * i + 2, 110 - item.Points[i].Y - 4);
             }
             context.lineTo(200, 106);
             context.closePath();
             context.lineWidth = 1;
             context.fillStyle = '#7FFF00' ;
             context.fill();
             context.strokeStyle = '#7CFC00' ;
             context.stroke();
             context.font = '12pt Calibri' ;
             context.fillStyle = 'white' ;
             context.fillText(item.Item.Name, 60, 20);
         }
         function addUploadItem(info) {
             if (cpus[info.ID] == null ) {
                 var pinfo = new ProcessorInfo();
                 pinfo.Item = info;
                 $( '<canvas id="processimg' + info.ID + '" width="200" height="110"></canvas>' ).appendTo($( '#lstProcessors' ));
                 cpus[info.ID] = pinfo;
                 processors.push(pinfo);
                 pinfo.Points.shift();
                 pinfo.Points.push( new Point(0, info.Percent));
                 drawProceessor(pinfo);
  
             } else {
                 var pinfo = cpus[info.ID];
                 pinfo.Points.shift();
                 pinfo.Points.push( new Point(0, info.Percent));
             }
         }

只需要通过定时器来不停地更新线程使用绘制即可.

?
1
2
3
4
5
setInterval( function () {
                 for ( var i = 0; i < processors.length; i++) {
                     drawProceessor(processors[i]);
                 }
             }, 1000);

服务端

对于服务端其实可以根据自己的需要来使用websocket协议实现,.net 4.5也提供相应的封装.而这里则使用了beetle对应websocket的扩展协议包,整体代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Program : WebSocketJsonServer
     {
         static void Main( string [] args)
         {
             TcpUtils.Setup( "beetle" );
             Program server = new Program();
             server.Open(8070);
             Console.WriteLine( "websocket start@8070" );
             ProcessorCounter counters = new ProcessorCounter();
             counters.Open();
             while ( true )
             {
                 ItemUsage[] items = counters.GetValues();
                 foreach (ItemUsage item in items)
                 {
                     Console.WriteLine( "{0}:{1}%" , item.Name, item.Percent);
                 }
                 JsonMessage message = new JsonMessage();
                 message.type = "cpu useage" ;
                 message.data = items;
                 foreach (TcpChannel channel in server.Server.GetOnlines())
                 {
                     channel.Send(message);
                 }
                 System.Threading.Thread.Sleep(995);
             }
             System.Threading.Thread.Sleep(-1);
         }
         protected override void OnError( object sender, ChannelErrorEventArgs e)
         {
             base .OnError(sender, e);
             Console.WriteLine(e.Exception.Message);
         }
         protected override void OnConnected( object sender, ChannelEventArgs e)
         {
             base .OnConnected(sender, e);
             Console.WriteLine( "{0} connected" , e.Channel.EndPoint);
         }
         protected override void OnDisposed( object sender, ChannelDisposedEventArgs e)
         {
             base .OnDisposed(sender, e);
             Console.WriteLine( "{0} disposed" , e.Channel.EndPoint);
            
         }
     }

每秒获取一次CPU的使用情况,并把信息以json的方式发送给当前所有在线的连接.

下载

完整代码:ProcessorsMonitor.rar (686.02 kb) 

演示地址:http://html5.ikende.com/ProcessorsMonitor.htm (浏览器使用chrome或IE10)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值