Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过http远程实时监视/控制服务器的正确方法_Javascript_Php_Ajax_Node.js - Fatal编程技术网

Javascript 通过http远程实时监视/控制服务器的正确方法

Javascript 通过http远程实时监视/控制服务器的正确方法,javascript,php,ajax,node.js,Javascript,Php,Ajax,Node.js,在我的客户端(带浏览器的手机)上,我想查看服务器CPU、RAM和HDD的状态,并从各种日志中收集信息 我正在使用ajax轮询 在客户端上,每5秒(setInterval)调用一个PHP文件: 扫描包含N个日志的文件夹 读取每个日志的最后一行 将其转换为JSON 问题: 每5秒打开一次新连接 多个AJAX调用 请求头(它们也是数据,因此会占用带宽) 响应头(^) 使用PHP每5秒读取一次文件。即使一切都没有改变 最后的JSON数据小于5 KB,但我每5秒发送一次,每次都有头文件和新连接,所以基本上

在我的客户端(带浏览器的手机)上,我想查看服务器CPU、RAM和HDD的状态,并从各种日志中收集信息

我正在使用ajax轮询

在客户端上,每5秒(setInterval)调用一个PHP文件:

  • 扫描包含N个日志的文件夹

  • 读取每个日志的最后一行

  • 将其转换为JSON

  • 问题:
  • 每5秒打开一次新连接
  • 多个AJAX调用
  • 请求头(它们也是数据,因此会占用带宽)
  • 响应头(^)
  • 使用PHP每5秒读取一次文件。即使一切都没有改变
  • 最后的JSON数据小于5 KB,但我每5秒发送一次,每次都有头文件和新连接,所以基本上每5秒,我必须发送5-10 KB才能得到5 KB,即10-20 KB

    这些是
    60秒/5秒=12
    每分钟新连接数,如果我保持应用程序打开,每小时流量约为15 MB

    假设我有100个用户,我让他们监视/控制我的服务器,一小时内大约有1.5 GB的传出流量

    更不用说PHP服务器每5秒读取多个文件100次

    我需要在服务器上每隔5秒读取这些日志的最后几行,并可能将它们写入文件,然后我只想在更改后将这些数据推送到客户端。


    SSE(服务器发送事件)和PHP

    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    while(true){
     echo "id: ".time()."\ndata: ".ReadTheLogs()."\n\n";
     ob_flush();
     flush();
     sleep(1);
    }
    
    在这种情况下,在与第一个用户建立连接之后 连接保持打开状态(PHP不是为此而设计的),因此我节省了一些空间(请求头、响应头)。这项工作在我的服务器上,但大多数服务器不允许长时间保持连接打开

    同时,对于多个用户,我会多次读取日志(降低旧服务器的速度) 我无法控制服务器。。。我需要使用ajax来发送命令

    我需要网袋


    node.js和WebSocket

    据我所知,使用node.js,我可以在不消耗大量资源的情况下完成所有这些工作 资源和班德维奇。连接保持打开,因此没有不必要的头,我可以接收和发送数据。它可以很好地处理多个用户

    这就是我需要你帮助的地方。

  • node.js服务器应该在后台更新,如果文件被修改,则每5秒存储一次日志数据。或者,操作系统应该使用(iwatch、dnotify…)

  • 只有在发生更改时才应推送数据

  • 日志读取应在5秒后仅发生一次。。。所以不是由每个用户触发的


  • 这是我发现并修改的第一个示例

    var ws=require("nodejs-websocket");
    var server=ws.createServer(function(conn){
    
        var data=read(whereToStoreTheLogs);
        conn.sendText(data)// send the logs data to the user 
        //on first connection.
    
        setTimeout(checkLogs,5000);
        /*
         here i need to continuosly check if the logs are changed.
         but if i use setInterval(checkLogs,5000) or setTimeout
         every user invokes a new timer and so having lots of timers on the server
         can i do that in background?         
        */
        conn.on("text",function(str){
         doStuff(str); // various commands to control the server.
        })
        conn.on("close",function(code,reason){
         console.log("Connection closed")
        })
    }).listen(8001);
    
    var checkLogs=function(){
     var data=read(whereToStoreTheLogs);
     if(data!=oldData){
      conn.sendText(data)
     }
     setTimeout(checkLogs,5000);
    }
    
    上面的脚本将是通知服务器,但我还需要找到一个解决方案来存储这些多个日志的信息,并在每次更改某些内容时在后台执行此操作

    您将如何保持bandwich较低,同时也保持服务器资源

    你会怎么做?

    编辑 顺便问一下,有没有一种方法可以同时将这些数据传输到所有客户机上

    编辑

    关于日志:我还希望能够缩放更新之间的时间扩展。。。我的意思是如果我阅读ffmpeg的日志,我会在可能的情况下每秒钟更新一次。。。但当没有转换处于活动状态时。。我需要每5分钟获取一次基本的机器信息,也许。。。等等

    目标: 1.执行读取和存储日志数据的方法(仅当clinets连接…[mysql,文件,可以将此信息存储在ram中(使用node.js??))。 2.将数据流传输到各种客户端(同时)的性能方法。 3.能够向服务器发送命令。。(双向) 4.使用web语言(js、php…)和lunix命令(易于在多台机器上实现)。。如果需要,免费软件

    最好的办法是:

    根据当前活动,将日志读到系统内存,并通过已打开的连接流同时连续地,读到带有WebSocket各种客户端

    我不知道还有什么比这更快的

    更新

    node.js服务器已经启动并运行,使用的是webSocketServer实现,因为它似乎是最快的实现。 我在@HeadCode的帮助下编写了以下代码,以正确处理客户情况&尽可能降低流程。检查广播回路中的各种内容。现在推送和客户处理处于一个良好的状态

    var 
    wss=new (require('ws').Server)({port:8080}),
    isBusy,
    logs,
    clients,
    i,
    checkLogs=function(){
     if(wss.clients&&(clients=wss.clients.length)){
      isBusy||(logs=readLogs()/*,isBusy=true*/);
      if(logs){
       i=0;
       while(i<clients){
        wss.clients[i++].send(logs)
       }
      }
     } 
    };
    setInterval(checkLogs,2000);
    
    var
    wss=new(require('ws').Server)({port:8080}),
    我很忙,
    日志,
    客户,
    我
    checkLogs=函数(){
    if(wss.clients&(clients=wss.clients.length)){
    isBusy | |(logs=readLogs()/*,isBusy=true*/);
    如果(日志){
    i=0;
    while(inodejs)输出实现
    
  • linux文件系统api
  • 请记住,我需要扫描各个文件夹中的日志,然后以某种方式解析输出的数据,并且每2秒进行一次

    注:如果日志读取系统是异步的,我将isBusy添加到服务器变量中

    编辑

    答案不完整。

    缺失:

  • 一种读取、解析和存储日志的高效方法(linux文件系统api或nodejs api,因此我将日志直接存储到系统内存中)
  • 如果可以直接将数据流传输给多个用户,则说明。 显然,nodejs通过客户端循环,因此(我认为)发送了多次数据
  • 顺便说一句,如果没有客户端,是否有可能/值得关闭节点服务器并在apache端重新启动新连接。(例如:如果我连接到apache托管的html文件,脚本将再次启动nodejs服务器)。这样做
    var express = require('express');
    var app = express();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    
    app.use(express.static(__dirname + '/'));
    app.get('/', function(req, res){
        res.sendfile('index.html');
    });
    
    io.on('connection', function(socket){
    
        // This is where we should emit the cached values of everything
        // that has been collected so far so this user doesn't have to
        // wait for a changed value on the monitored host to see
        // what is going on.
        // This code is based on something I wrote for myself so it's not
        // going to do anything for you as is.  You'll have to implement
        // your own caching mechanism.
        for (var stat in cache) {
            if (cache.hasOwnProperty(stat)) {
                socket.emit('data', JSON.stringify(cache[stat]));
            }
        }
    });
    
    http.listen(3000, function(){
        console.log('listening on *:3000');
    });
    
    (function checkLogs(){
        var data=read(whereToStoreTheLogs);
        if(data!=oldData){
            io.emit(data)
        }
        setTimeout(checkLogs,5000);
    })();
    
    <script src="/path/to/socket.io.js"></script>
    <script>
    
        // Set up the websocket for receiving updates from the server
        var socket = io();
    
        socket.on('data', function(msg){
            // Do something with your message here, such as using javascript
            // to display it in an appropriate spot on the page.
            document.getElementById("content").innerHTML = msg;
        });
    
    </script>
    
    <!DOCTYPE HTML>
    <html>
    <head>
    <meta charset="utf-8">
    <title>WS example</title>
    </head>
    <body>
    <script>
    var connection;
    window.addEventListener("load", function () {
        connection = new WebSocket("ws://"+window.location.hostname+":8001")
        connection.onopen = function () {
            console.log("Connection opened")
        }
        connection.onclose = function () {
            console.log("Connection closed")
        }
        connection.onerror = function () {
            console.error("Connection error")
        }
        connection.onmessage = function (event) {
            var div = document.createElement("div")
            div.textContent = event.data
            document.body.appendChild(div)
        }
    });
    </script>
    </body>
    </html>
    
    var ws = require("nodejs-websocket")
    var os = require('os');
    Tail = require('tail').Tail;
    tail = new Tail('./testlog.txt');
    
    var server = ws.createServer(function (conn) {
        conn.on("text", function (str) {
            console.log("Received " + str);
        });
        conn.on("close", function (code, reason) {
            console.log("Connection closed");
        });
    }).listen(8001);
    
    
    setInterval(function(){ checkLoad(); }, 5000);
    
    
    function broadcast(mesg) {
        server.connections.forEach(function (conn) {
            conn.sendText(mesg)
        })
    }
    
    var load = '';
    function checkLoad(){
        var new_load = os.loadavg().toString();
        if (new_load === 'load'){
            return;
        }
        load = new_load;
        broadcast(load);
    }
    
    tail.on("line", function(data) {
        broadcast(data);
    });