[转载] Github 开源项目(一)websocketd (实战:实时监控服务器内存信息)
转载 https://www.cnblogs.com/tinywan/p/6826125.html
官方地址:https://github.com/joewalnes/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 看是否配置合适,如下所示:
[email protected]:~/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 服务
[email protected]:~/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
运行脚本时你可能会遇到以下错误:
[email protected]:/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 + '\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 实时监控内存信息
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="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>
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 文件 ([email protected]:~/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); };