欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

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

 

应用效果

 

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

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

 

C#获取CPU使用情况
 

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

 

  int coreCount = Environment.ProcessorCount;         

            for (int i = 0; i < coreCount; i++) 

            { 

                mCounters.Add(new PerformanceCounter("Processor", "% Processor Time", i.ToString())); 

            } 

 

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

 

  /// <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所有线程使用情况计数的类就完成了.

 

页面绘制处理

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

 

  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个点的曲线这样一个动态的走势就可以完成了.

 

  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)); 

            } 

        } 

 

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

 

  setInterval(function () { 

                for (var i = 0; i < processors.length; i++) { 

                    drawProceessor(processors[i]); 

                } 

            }, 1000); 

 

服务端

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

 

 

  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的方式发送给当前所有在线的连接.