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

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

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

【总目录】



【本文简介】


   上文我们编写了一个实时获取服务器内存使用情况的demo,单纯从逻辑上来看,这个demo没有问题。但是,现在我们设想一下,如果一个用户连接服务器,那个每秒会执行一次free命令,然后会向客户端发送一次数据,如果有十个用户,那个对于服务器来说,他每秒就不知执行一次free命令,如果是上千,上万个用户连接到服务器呢,那这对服务器的负担是非常大的。所以,我们现在要来优化这个服务器端的代码。

【思路】


    大体思路就是将返回数据给用户的定时行为,跟更新内存状态的行为分开:

1.当用用户连接时,开启一个计时器,每秒计算一次内存状态,并且将这个结果保存到一个全局变量中。
2.用户本身还需要开启一个计时器,每秒会去全局变量拉取内存的状态,然后返回给客户端呈现。
3.当所有用户都处于断开连接时,服务器处于挂起状态,不在去获取内存状态的变化,节省了资源浪费。

这样,不管有多少个用户连接到服务器,更新内存的状态的行为只会每秒执行一次。

优化后的服务器代码如下:

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


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

var mem = {};

var clientMemUpdater = undefined;


function updateMemInfo(){
        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);
                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]);

                }
        });
}
updateMemInfo();

wss.on('connection',function(ws){
        var clientMemSend;
        var sendMemUpdates = function(ws){
                if(ws.readyState == 1){
                        ws.send(JSON.stringify(mem));
                }
        }
        clientMemSend = setInterval(function(){
                if(typeof clientMemUpdater == 'undefined'){
                        clientMemUpdater = setInterval(updateMemInfo,1000);
                }
                sendMemUpdates(ws);
        },1000);

        sendMemUpdates(ws);
        if(typeof clientMemUpdater == 'undefined'){
                clientMemUpdater = setInterval(updateMemInfo,1000);
        }
        ws.on("close",function(){
                if(typeof clientMemSend != 'undefined'){
                        clearInterval(clientMemSend);
                }
                if(typeof clientMemUpdater !='undefined'){
                        clearInterval(clientMemUpdater);
                        clientMemUpdater = undefined;
                }
        });
});

   通过测试,上面的优化对比之前的方案,当客户端不断增加时,内存消耗的区别就会越明显,读者可以自己跑跑代码,体验一下。

【演示地址】


电脑访问:

手机浏览器、微信访问:



【源码下载】




【结束语】


    在做多次测试过程中,我发现,当我开启多个客户端,然后关闭所有客户端时,内存并没有被释放,直到我手动停止了服务器,内存才会被回收。
     我的解决方法是,安装 memwatch,在连接建立 和 关闭 的时候都调用 memwatch.gc() 方法,强制内存回收,可以起到一定的作用。如果大家有更好的解决方案,可以在留言处分享!

猜你喜欢

转载自blog.csdn.net/u010136741/article/details/51590619
今日推荐