Github 開源項目(一)websocketd (實戰:實時監控服務器內存信息)

websocketd 是WebSocket守護進程,它負責處理WebSocket鏈接,啓動您的程序來處理WebSockets,並在程序和Web瀏覽器之間傳遞消息。javascript

 安裝: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

解壓後生成這個文件:websocketdphp

複製該文件到 /usr/bin目錄下,修改環境變量html

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

可能出現的錯誤:若是修改了/etc/profile,那麼編輯結束後執行source profile 或 執行點命令 ./profile,PATH的值就會當即生效了,可是會提示如下錯誤:java

#source /etc/profile   以後爲何會出現
command not found

解決辦法,直接切換到root 用戶模式既可,再次執行source profile 就能夠了,輸入help 看是否配置合適,以下所示:jquery

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.shlinux

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

運行腳本時你可能會遇到如下錯誤:git

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

請賦予權限,使其可執行:github

$ chmod +x ./count.sh

隨便打開一個瀏覽器,在console中輸入一下代碼測試:web

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)測試結果以下所示:sql

(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 + '\n'; } // 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 實時監控內存信息

一、編寫腳本,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

二、客戶端實時監控代碼:

<div class="panel-footer" id="container" style="width: 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, width: 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>

三、測試結果:

 

四、客戶端可能會出現超時連接的,可使用 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 代理服務器

一、沒代理以前訪問

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); };

二、代理以後訪問

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; width: 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']]). "\n";
    usleep(5000000);
}

 

注意:開頭的PHP路徑爲絕對路徑

相關文章
相關標籤/搜索