zoukankan      html  css  js  c++  java
  • Github 开源项目(一)websocketd (实战:实时监控服务器内存信息)

    websocketd 是WebSocket守护进程,它负责处理WebSocket连接,启动您的程序来处理WebSockets,并在程序和Web浏览器之间传递消息。

     安装:websocketd 

    wget https://github.com/joewalnes/websocketd/releases/download/v0.2.12/websocketd-0.2.12-linux_amd64.zip
    
    unzip  websocketd-0.2.12-linux_amd64.zip

    解压后生成这个文件:websocketd

    复制该文件到 /usr/bin目录下,修改环境变量

    sudo cp websocketd /usr/bin/websocketd
    
    sudo vim /etc/profile
    
    export  PATH=$PATH:/usr/bin/websocketd

    可能出现的错误:如果修改了/etc/profile,那么编辑结束后执行source profile 或 执行点命令 ./profile,PATH的值就会立即生效了,但是会提示以下错误:

    #source /etc/profile   之后为什么会出现
    command not found

    解决办法,直接切换到root 用户模式既可,再次执行source profile 就可以了,输入help 看是否配置合适,如下所示:

    tinywan@tinywan:~/shell$ websocketd --help
    websocketd (0.2.12 (go1.6 linux-amd64) --)
    
    websocketd is a command line tool that will allow any executable program
    that accepts input on stdin and produces output on stdout to be turned into
    a WebSocket server.
    
    Usage:
    
      Export a single executable program a WebSocket server:
        websocketd [options] COMMAND [command args]
    
      Or, export an entire directory of executables as WebSocket endpoints:
        websocketd [options] --dir=SOMEDIR
    
    Options:
    
      --port=PORT                    HTTP port to listen on.
    
      --address=ADDRESS              Address to bind to (multiple options allowed)
                                     Use square brackets to specify IPv6 address. 
                                     Default: "" (all)

    开启WebSocketd 服务Tinywan

    tinywan@tinywan:~/shell$ websocketd --port=63800 ./count.sh 
    Mon, 08 May 2017 17:26:50 +0800 | INFO   | server     |  | Serving using application   : ./count.sh 
    Mon, 08 May 2017 17:26:50 +0800 | INFO   | server     |  | Starting WebSocket server   : ws://tinywan:8080/

    测试代码:count.sh

    #!/bin/bash
    for ((COUNT = 1; COUNT <= 10; COUNT++)); do
      echo $COUNT
      sleep 1
    done

    运行脚本时你可能会遇到以下错误:

    root@TinywanAliYun:/home/www/bin# websocketd --port=63800 ./count.sh 
    Unable to locate specified COMMAND './count.sh' in OS path.
    
    Usage:
    
      Export a single executable program a WebSocket server:
        websocketd [options] COMMAND [command args]
    
      Or, export an entire directory of executables as WebSocket endpoints:
        websocketd [options] --dir=SOMEDIR
    
      Or, show extended help message using:
        websocketd --help

    请赋予权限,使其可执行:

    $ chmod +x ./count.sh

    随便打开一个浏览器,在console中输入一下代码测试:

    var ws = new WebSocket('ws://192.168.18.12:63800/');
    ws.onopen = function() {
        console.log('CONNECT');
    };
    ws.onclose = function() {
        console.log('DISCONNECT');
    };
    ws.onmessage = function(event) {
        console.log('MESSAGE: ' + event.data);
    };

    (1)测试结果如下所示:

    (2)新建立一个客户端测试client.html

    <!doctype html>
    <html lang="">
    <head>
        <meta charset="utf-8">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>websocketd</title>
    </head>
    <body>
    <h2>websocketd 客户端的简单测试</h2>
    <pre id="log"></pre>
    <script>
        // helper function: log message to screen
        function log(msg) {
            document.getElementById('log').textContent += msg + '
    ';
        }
    
        // setup websocket with callbacks
        var ws = new WebSocket('ws://192.168.18.12:8080/');
        ws.onopen = function() {
            console.log('CONNECT');
        };
        ws.onclose = function() {
            console.log('DISCONNECT');
        };
        ws.onmessage = function(event) {
            console.log('MESSAGE: ' + event.data);
        };
    </script>
    </body>
    </html>

    在查看结果信息,查看结果已经ok

     查看服务端信息

    我本机IP地址为,也就是client.html客户端

     websocketd --port=9501 --devconsole luajit ./json_ws.lua

    》》》实际案例,使用WebSocketd 实时监控内存信息

    1、编写脚本,system_info_send_websocketd.sh

    #!/bin/bash
    PATH=/usr/local/bin:/usr/bin:/bin
    
    SHELL_DIR="/home/www/bin"
    SHELL_NAME="system_info_websocketd"
    SHELL_TIME=$(date '+%Y-%m-%d')
    SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}-${SHELL_TIME}.log"
    
    REDIS_MEMORY_KEYS_NAME="REDIS_MEMORY_INFO:001"
    REDIS_DISH_KEYS_NAME="REDIS_DISH_INFO:001"
    
    while(true)
        do
            FIND_DATA=$(cat /proc/meminfo | grep "MemFree:" | awk '{print $2}')
            echo  "[$SHELL_TIME]: FIND_DATA = $FIND_DATA INSERT_RES = ${INSERT_RES} CUT_LIST_LEN = ${CUT_LIST_LEN}" >> $SHELL_LOG
            echo   '{"data":'"${FIND_DATA}"',"errcode":0,"errmsg":0}'
            sleep 2
    done

    2、客户端实时监控代码:

    <div class="panel-footer" id="container" style=" 100%; height: 400px; margin: 0 auto"></div>
    <script language="JavaScript">
        //数据获取
        var moniServerIp = "{{moniServerIp}}";
        var moniServerSshUsername = "{$moniServerSshUsername}";
        var moniServerSshPassword = "{$moniServerSshPassword}";
    
        var wsServerIP = "127.0.0.1";
        var wsServerPort = "12380";
        var moniMehtod = "server02";
        var moniInterval = 1;
        var moniDataUnit = 'MB';
    
        var wsData = 0.0;
        wsSend = {
            "action": moniMehtod,
            "name": "tinywan",
        };
        $(document).ready(function () {
            //----------WebSocket部分--------------
            var ws = new WebSocket("ws://" + wsServerIP + ":" + wsServerPort);
            ws.onopen = function () {
                ws.send(JSON.stringify(wsSend));
            };
            ws.onclose = function () {
                console.log('链接已断开');
                ws.close();
            };
            ws.onmessage = function (e) {
                var response = JSON.parse(e.data);
                if (Number(response.errcode) !== 0) {
                    console.log(String(response.errmsg));
                    ws.close();
                    alert('出错啦!' + String(response.errmsg));
                    return;
                }
                var divisor = 1;
                switch (moniDataUnit.toLocaleLowerCase()) {
                    case 'mb':
                        divisor = 1024;
                        break;
                }
                wsData = response.data / divisor;
                console.log("收到服务端的消息:" + wsData);
            };
    
            //----------highcharts的图标插件部分--------------
            Highcharts.setOptions({
                global: {
                    useUTC: false
                }
            });
    
            $('#container').highcharts({
                chart: {
                    type: 'spline',
                    animation: Highcharts.svg, // don't animate in old IE
                    marginRight: 10,
                    events: {
                        load: function () {
                            // set up the updating of the chart each second
                            var series = this.series[0];
                            setInterval(function () {
                                // current time
                                var x = (new Date()).getTime(),
                                    y = wsData * 1.00;
                                series.addPoint([x, y], true, true);
                            }, 2000);
                        }
                    }
                },
                title: {
                    text: '服务器【' + moniServerIp + '】内存指标(单位:' + moniDataUnit + ')'
                },
                xAxis: {
                    type: 'datetime',
                    tickPixelInterval: 150
                },
                yAxis: {
                    title: {
                        text: 'MemFree'
                    },
                    plotLines: [{
                        value: 0,
                         1,
                        color: '#808080'
                    }]
                },
                tooltip: {
                    formatter: function () {
                        return '<b>' + this.series.name + '</b><br/>' +
                            Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
                            Highcharts.numberFormat(this.y, 2);
                    }
                },
                legend: {
                    enabled: false
                },
                exporting: {
                    enabled: false
                },
                series: [{
                    name: 'MemFree指标',
                    data: (function () {
                        // generate an array
                        var data = [],
                            time = (new Date()).getTime(),
                            i;
                        for (i = -19; i <= 0; i += 1) {
                            data.push({
                                x: time + i * 1000,
                                y: wsData
                            });
                        }
                        return data;
                    }())
                }]
            });
        });
    </script>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="http://code.highcharts.com/highcharts.js"></script>

    3、测试结果:

     

    4、客户端可能会出现超时链接的,可以使用 ReconnectingWebSocket

     var ws = new ReconnectingWebSocket("ws://" + wsServerIP + ":" + wsServerPort);

     》》》》》》》》》》》》 参数详解                   

    (1)参数一:--staticdir=.

    --staticdir=.  Allow websocketd to serve count.html as a static file
    //允许websocketd作为静态文件提供count.html

    这个参数是什么意思来,就是在当前项目指定通知执行的语言脚本文件(count.sh)同名的count.html作为静态文件,直接使用http访问

    当前目录

    count.sh 文件 (tinywan@tinywan:~/Go/websocket$ cat count.sh)

    #!/bin/bash
    # Count from 1 to 10, pausing for a second between each iteration.
    for COUNT in $(seq 1 10); do
      echo $COUNT
      sleep 1
    done

    count.html 文件

    <!DOCTYPE html>
    <html>
      <head>
        <title>websocketd count example</title>
        <style>
          #count {
            font: bold 150px arial;
            margin: auto;
            padding: 10px;
            text-align: center;
          }
        </style>
      </head>
      <body>
    
        <div id="count"></div>
    
        <script>
          var ws = new WebSocket('ws://192.168.18.180:8080/');
          ws.onopen = function() {
            document.body.style.backgroundColor = '#cfc';
          };
          ws.onclose = function() {
            document.body.style.backgroundColor = null;
          };
          ws.onmessage = function(event) {
            document.getElementById('count').textContent = event.data;
          };
        </script>
    
      </body>
    </html>

     打开谷歌浏览器,在地址栏输入:http://192.168.18.180:8080/

      

    点击count.html后的效果图

       

     (2)参数二: --devconsole

      该--devconsole标志使内置的控制台websocketd与WebSocket端点手动交互。

      指向浏览器http://localhost:8080/,您将看到控制台。按复选框连接。

          请注意,您不能同时使用--devconsole和--staticdir。开发控制台旨在提供临时用户界面,直到您构建了真实的用户界面。

    开始测试:

      

    打开浏览器测试,发送一个空数据是没办法发送的,由于我们没有指定开启那个一个语言脚本文件充当WebSocket 服务器,为我们提供客户端的服务

      

    指定/home/tinywan/Go/websocket 目录下的 count.sh 作为服务文件,继续测试的结果如下所示

      

     Websocket 代理服务器

    1、没代理之前访问

    var ws = new WebSocket('ws://192.168.18.188:63800');
    ws.onopen = function() {
        console.log('CONNECT');
    };
    ws.onclose = function() {
        console.log('DISCONNECT');
    };
    ws.onmessage = function(event) {
        console.log('MESSAGE: ' + event.data);
    };

    2、代理之后访问

    var ws = new WebSocket('ws://192.168.18.188:8087/chat/');
    ws.onopen = function() {
        console.log('CONNECT');
    };
    ws.onclose = function() {
        console.log('DISCONNECT');
    };
    ws.onmessage = function(event) {
        console.log('MESSAGE: ' + event.data);
    };

    守护进程运行

    nohup websocketd --port=63800 /home/www/bin/system_info_send_all_websocketd.sh >/dev/null  2>&1 &

     加载证书

     sudo websocketd --port=6500 --ssl --sslcert="/etc/letsencrypt/live/www.tinywan.top/fullchain.pem" --
    
    sslkey="/etc/letsencrypt/live/www.tinywan.top//privkey.pem" /home/www/bin/system_info_send_all_websocketd.s

     wss 协议测试

    var ws = new WebSocket('wss://www.tinywan.top:6500');
    ws.onopen = function() {
        console.log('CONNECT');
    };
    ws.onclose = function() {
        console.log('DISCONNECT');
    };
    ws.onmessage = function(event) {
        console.log('MESSAGE: ' + event.data);
    };

    实时监控服务器日志信息

    服务端执行脚本执行脚本 

    $ websocketd --port=63800 ./system_info_send_all_websocketd.sh 
    Sun, 09 Sep 2018 14:34:55 +0800 | INFO   | server     |  | Serving using application   : .../system_info_send_all_websocketd.sh 
    Sun, 09 Sep 2018 14:34:55 +0800 | INFO   | server     |  | Starting WebSocket server   : ws://iZ2zec3dge6rwz2uw4tveuZ:63800/
    Sun, 09 Sep 2018 14:35:30 +0800 | ACCESS | session    | url:'http://159.110.213.20:63800/websocket/' id:'1536474930878947882' remote:'60.186.221.134' command:'/home/www/bin/system_info_send_all_websocketd.sh' origin:'file://' | CONNECT

    本地随便新建以下文件内容

    <!DOCTYPE html>
    <html>
    
    <head>
        <style>
            body{
                background-color: #0e1012;color: #ffffff;
            }
            *{
                margin: 0; padding: 0;
            }
            #msg{
                overflow:auto; border:2px solid #303030; color:#ffffff; background-color: #2b2b2b; font-size: 13px; position: absolute; left: 8px; right: 8px; bottom: 8px; top: 40px; word-break:
    break-all;
            }
            #log{
                position: fixed; top: 0; left: 0;  100%; height: 40px; text-align: left; margin: 4px 0 0 8px;
            }
            #log b{
                font-size: 26px;
            }
            #msgBtn{
                padding: 5px 10px; border: none; background: #777; float: right; margin: 0 16px 0 0;
            }
        </style>
    </head>
    
    <body>
        <div id="log"><span><b>服务器实时日志</b></span><button id="msgBtn" type="button">清空</button></div>
        <div id="msg">
            <ul class="list"></ul>
        </div>
        <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
        <script>
            $(document).ready(function () {
                if (!window.WebSocket) {
                    if (window.MozWebSocket) {
                        window.WebSocket = window.MozWebSocket;
                    } else {
                        $('#msg').append("<p>你的浏览器不支持websocket</p>");
                    }
                }
                var ws = new WebSocket('ws://www.tinywan.com:63800/websocket/');
                ws.onopen = function (evt) {
                    $('.list').append('<li>websocket连接成功</li>');
                }
                ws.onmessage = function (evt) {
                    $('.list').append('<li>' + evt.data + '</li>');
                    setTimeout(function () {
                        $('#msg').scrollTop($('.list').height() - $('#msg').height());
                    }, 100)
                }
                $("#msgBtn").click(function () {
                    $(".list").html("");
                })
            });
        </script>
    </body>
    </html>  

    浏览器打开log.html效果:

     

    Nginx 代理配置

    server {
        listen 443 ssl http2;
        server_name wallet.www.top;
    
        ssl_certificate /etc/letsencrypt/wallet.www.top/full_chain.pem;
        ssl_certificate_key /etc/letsencrypt/wallet.www.top/private.key;
    
        location /wssd
        {
            proxy_pass http://lnmp-php:8888;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_read_timeout 600;
    
        }
    }

    连接方式

    var ws = new WebSocket('wss://wallet.www.top/wssd');

    运行一个PHP案例

    #!/usr/local/php/bin/php
    <?php
    
    require_once './vendor/autoload.php';
    
    $db = new MysqliDb ([
        'host' => '127.0.0.1',
        'username' => 'test',
        'password' => 'test',
        'db' => 'test',
        'port' => 3308,
        'prefix' => 'cl_',
        'charset' => 'utf8'
    ]);
    
    $params = [1, -1];
    while (true){
        $users = $db->rawQuery("SELECT count(*) as nums FROM cl_investor WHERE is_order_taking = ? AND ws_online = ?", $params);
        echo json_encode(['counts'=>$users[0]['nums']]). "
    ";
        usleep(5000000);
    }
    

    注意:开头的PHP路径为绝对路径

      

  • 相关阅读:
    C#学习笔记之——矩形覆盖问题
    链表,栈,队列代码
    链表练习代码
    2012年全国计算机专业大学排名
    寄存器介绍
    win8 wifi开关显示关闭,且设置里面wifi开关显示灰色的解决办法
    360随身wifi无法使用临时解决方案大全
    锐捷客户端的校园网电脑如何转化成无线路由
    未完成数据结构题目
    数据结构代码1
  • 原文地址:https://www.cnblogs.com/tinywan/p/6826125.html
Copyright © 2011-2022 走看看