由于WebSocket允许保持长连接,因此当建立连接后服务器可以主动地向Client发送相关信息.下面通过服务端获取当前CPU的使用情况主动发送给网页,让网页实时显示CPU使用情况的曲线图.该事例的主要功能是包括服务端获取CPU使和情况和HTML5使用canvas进行曲线图绘制.
实现效果主要是模仿windows的任务管理器,显示每个核的工作情况.
可能通过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)
via:http://www.cnblogs.com/smark/archive/2012/12/25/2833129.html
如何将 HTML5 性能发挥到极致由于实际运行环境是在浏览器中,因此性能还取决于JavaScript解释器的效率,指定的FPS帧速在低性能解释器中可能不会
HTML5 VideoAPI,打造自己的Web视频播放器本文将使用HTML5提供的VideoAPI做一个自定义的视频播放器,需要用到HTML5提供的video标签、以及HTML5提供的对JavascriptAP
HTML5 手势检测原理和实现随着 Hybrid 应用的丰富,HTML5 工程师们已经不满足于把桌面端体验简单移植到移动端,他们觊觎移动原生应用人性化的
4分钟学会网页样式[译]你想要在自己网站上分享一个产品,或者是一个作品集,又或者仅仅只是一个灵感。在你发布到网上之前,你想让它
H5你真的了解吗?(绝对干货)H5广告,包括H5广告的设计流程,究竟有什么讲究,和阶段。为了能帮助更多的人了解H5广告,我专门做了一个讲义。
2015-2016前端架构体系技术精简版本文主要内容有:框架与组件、构建生态、开发技巧与调试、html、css与重构、native/hybrid/桌面开发、前端/H5优化、全