WebSocket入门教程(三)-- WebSocket实例:实时获取服务器内存使用情况

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010136741/article/details/51581298

转载请标明出处:http://blog.csdn.net/u010136741/article/details/51581298, 本文出自: 柳木木_kylin

【总目录】



【实例简介】


  前面我们已经介绍了WebSocket的概念和WebSocket的Api,下面我们通过一个简单的实例,来实际体验一下WebSocket。
  下面,我们要展示的是一个实时获取服务器内存使用情况的一个案例。用户打开页面,通过websocket连接到服务器,服务器每隔一秒钟,会返回服务器内存的使用情况,达到对内存的实时监控,作为运维人员来说,可以通过微信,手机浏览器等实现对服务器状态的实时监听。

【客户端】


    首先,我们需要设计一个简单的页面,页面主要包含一个表格,表格会列出内存的总容量、正在使用的内存、闲置的内存、以及写缓存和读缓存。
    我们先看看客户端的头部,再来讲解思路:

<!DOCTYPE html>
<html lang="en">
<head>
<title>WebSocket入门教程(三)-- WebSocket实例:实时获取服务器内存使用情况</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.css">
    <link rel="stylesheet" href="http://cdn.bootcss.com/tether/1.3.2/css/tether.css"/>
    <script src="http://cdn.bootcss.com/jquery/2.2.4/jquery.js" ></script>
    <script src="http://cdn.bootcss.com/tether/1.3.2/js/tether.js"></script>
    <script src="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/js/bootstrap.js"></script>
    <script>
    // code from chapter goes here
        $(function() {
                //alert("xxx");
                var ws = new WebSocket("ws://www.liumumu.top:8181");

                var mem = {"total": 0,
                          "used": 0,
                          "free": 0,
                          "buffers": 0,
                          "cached": 0};
                ws.onopen = function(e){
                        console.log("Connection established");

                };

                var changeMemEntry = function(field,originalValue,newValue){
                        var valElem = $('#' + field + ' span');
                        valElem.html(newValue);
                        if(originalValue == 0){
                                return;
                        }
                        if(field =="free"){
                                if(newValue < originalValue){
                                        valElem.addClass('label-danger');
                                        valElem.removeClass('label-success');
                                }else if(newValue>originalValue){
                                        valElem.addClass('label-success');
                                        valElem.removeClass('label-danger');
                                }
                        }else{
                                if(newValue > originalValue){
                                        valElem.addClass('label-danger');
                                        valElem.removeClass('label-success');
                                }else if(newValue<originalValue){
                                        valElem.addClass('label-success');
                                        valElem.removeClass('label-danger');
                                }
                        }

                }
                ws.onmessage = function(e){
                        var memData = JSON.parse(e.data);
                        //console.log("onmessage",memData);
                        for(var field in memData){
                                if(memData.hasOwnProperty(field)){

                                        changeMemEntry(field,mem[field],memData[field]);
                                        mem[field] = memData[field];
                                }
                        }
                }
                ws.onerror = function(e){
                        console.log("WebSocket failure,error",e);
                        //handleErrors(e);
                }
                ws.onclose = function(e){
                        console.log(e);
                        console.log(e.reason+" "+e.code);
                        for(var field in mem){
                                if(mem.hasOwnProperty(field)){
                                        mem[field] = 0;
				}
                        }
                }


        });
    </script>
    <style>
        html,body{
                height:100%;

        }
    </style>
</head>
<body lang="cn">
    <div class="vertical-center">
        <div class="container">
            <h1 style="text-align:center;padding:5px;">柳木木ECS概况</h1>
            <table class="table" id="memTable">
            <thead>
                <tr>
                <th>类型</th>
                <th>大小(KB)</th>
                </tr>
            </thead>
            <tbody id="memRows">
            <tr>
                <td><h3>内存总量</h3></td>
                <td id="total">
                <h3><span class="label label-default label-success">0.00</span></h3>
                </td>
            </tr>
            <tr>
                <td><h3>已使用内存</h3></td>
                <td id="used">
                <h3><span class="label label-default label-success">0.00</span></h3>
                </td>
            </tr>
            <tr>
                <td><h3>闲置内存</h3></td>
                <td id="free">
                <h3><span class="label label-default label-success">0.00</span></h3>
                </td>
            </tr>
            <tr>
                <td><h3>写缓存</h3></td>
                <td id="buffers">
                <h3><span class="label label-default label-success">0.00</span></h3>
                </td>
            </tr>
            <tr>                
	        <td><h3>读缓存</h3></td>
                <td id="cached">
                <h3><span class="label label-default label-success">0.00</span></h3>
                </td>
            </tr>
            </tbody>
            </table>
        </div>
    </div>
</body>
</html>

    准备工作,我们先引入了jquery,bootstrap库,用于样式呈现。
    首先我们连接服务器,然后给每个字段附上初始值0,定义了changeMemEntry用来更新页面的数据和样式。
在onmessage回调方法里,我们将接收到的json字符串解析成json对象,然后遍历对象的每个属性,将属性值传递给changeMemEntry,实现数据的更新。在onclose回调方法里,我们将数据清0。

页面的展示效果如下图:



【服务器端】

    本案例服务器端,我们通过nodejs实现,大体步骤如下
1.创建websocket服务,监听8181端口。
2.当客户端请求连接并且连接成功时,运行linux的free命令,获取内存信息,通过正则将标准输出字符串,转换成json对象,然后返回给客户端。
3.开始定时器,每一秒钟执行循环第2步操作。
4.当连接关闭时,清除定时器。

//send memory info per seconds
var WebSocketServer = require('ws').Server,
        wss = new WebSocketServer({port:8181});


var spawn = require('child_process').spawn;

function sendMemInfo(ws){
        var free = spawn('free',['-k']);
        free.stdout.on('data',function(data){
                var strdata = ""+data;
                //console.log(strdata);
                //正则匹配,获取数据
                var re = /Mem: *(\d*) *(\d*) *(\d*) *(\d*) *(\d*) *(\d*)/;
                var result = strdata.match(re);
                var mem = {};
                if(result.length>0){
                        mem["total"] = parseInt(result[1]);
                        mem["used"] = parseInt(result[2]);
                        mem["free"] = parseInt(result[3]);
                        //mem["shared"] = parseInt(result[4]);
                        mem["buffers"] = parseInt(result[5]);
                        mem["cached"] = parseInt(result[6]);
                        ws.send(JSON.stringify(mem));
                }
        });
}

wss.on('connection',function(ws){
        var clientMemUpdater;
        var sendMemUpdates = function(ws){
                if(ws.readyState == 1){
                        sendMemInfo(ws);
                }
        }
        clientMemUpdater = setInterval(function(){
                sendMemUpdates(ws);
        },1000);
        var clientStocks = [];
        sendMemUpdates(ws);
        ws.on("close",function(){
                if(typeof clientMemUpdater != 'undefined'){
                        clearInterval(clientMemUpdater);
                }
        });
});

【演示地址】


电脑访问:

手机浏览器、微信访问:



【源码下载】




【结束语】


    在写这篇文章的时候,我发现了这个demo存在的一个性能隐患,有没读者也发现了这个问题,欢迎留言吐槽!

猜你喜欢

转载自blog.csdn.net/u010136741/article/details/51581298