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.-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. (go1. 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= ./count.sh
Mon, May :: + | INFO | server | | Serving using application : ./count.sh
Mon, May :: + | INFO | server | | Starting WebSocket server : ws://tinywan:8080/

测试代码:count.sh

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

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

root@TinywanAliYun:/home/www/bin# websocketd --port= ./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
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 文件 (tinywan@tinywan:~/Go/websocket$ cat count.sh)

#!/bin/bash
# Count from to , pausing for a second between each iteration.
for COUNT in $(seq ); do
echo $COUNT
sleep
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= /home/www/bin/system_info_send_all_websocketd.sh >/dev/null  >& &

加载证书

 sudo websocketd --port= --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路径为绝对路径

  

Github 开源项目(一)websocketd (实战:实时监控服务器内存信息)的更多相关文章

  1. 开源项目福利-github开源项目免费使用Azure PipeLine

    微软收购Github后,很多人猜想微软可能会砍掉VSTS,然而事实VSTS并没有砍掉,关于Azure Devops的详细信息可以查看 这篇博客,如果想查看原文也可以从链接里提供的原始地址里查看. 今天 ...

  2. 2015-2016最火的Android开源项目--github开源项目集锦(不看你就out了)

    标签: Android开发开源项目最火Android项目github 2015-2016最火的Android开源项目 本文整理与集结了近期github上使用最广泛最火热与最流行的开源项目,想要充电与提 ...

  3. 如何参与一个 GitHub 开源项目?

    最近一年开源项目特别的热,很多技术大会或论坛都以开源项目作为主题进行探讨,可见这是一种趋势.而Github作为开源项目的著名托管地,可谓无 人不知,越来越多的个人和公司纷纷加入到Github的大家族里 ...

  4. Android笔记——导入Github开源项目CircleRefreshLayout

    百度n久都找不到android studio导入第三方类库的正确方法,纠结睡不着 ,最后终于蒙到了方法,原来想太多了  ---------------------------------------- ...

  5. 如何参与一个GitHub开源项目

    Github作为开源项目的著名托管地,可谓无人不知,越来越多的个人和公司纷纷加入到Github的大家族里来,为开源尽一份绵薄之力.对于个人来讲,你把自己的项目托管到Github上并不表示你参与了Git ...

  6. 基于RBAC模型的权限系统设计(Github开源项目)

    RBAC(基于角色的访问控制):英文名称Rose base Access Controller.本博客介绍这种模型的权限系统设计.取消了用户和权限的直接关联,改为通过用户关联角色.角色关联权限的方法来 ...

  7. Android Hawk数据库 github开源项目

    Android Hawk数据库 github开源项目 Hawk 是一个很便捷的数据库  . 操作数据库仅仅需一行代码 , 能存不论什么数据类型 . github 地址: https://github. ...

  8. [Android开源项目] GitHub开源项目总结 (转)

    [Android开源项目] GitHub开源项目总结 GitHub开源项目android-styled-dialogs http://neast.cn/forum.php?mod=viewthread ...

  9. iOS:开发常用GitHub开源项目(持续更新)

    IOS开发常用GitHub开源项目(持续更新) 数据类 开源库 作者 简介 AFNetworking Mattt 网络请求库 ASIHTTPRequest pokeb 网络请求库 Alamofire ...

随机推荐

  1. Android探究之View的绘制流程

    Android中Activity是作为应用程序的载体存在,代表着一个完整的用户界面,提供了一个窗口来绘制各种视图,当Activity启动时,我们会通过setContentView方法来设置一个内容视图 ...

  2. [20190419]shared latch spin count 2.txt

    [20190419]shared latch spin count 2.txt --//上午测试shared latch XX模式的情况,链接:http://blog.itpub.net/267265 ...

  3. About A Scam

    事件起因 本篇记录一个我遇到一个诈骗故事. 这两年我陆续有收到邮件,内容为有一大笔遗产我可以继承,让我提供银行卡号,身份证号相关信息. 后面邮件的内容就变为,有一笔公益款项,可以用我名义去管理,让我提 ...

  4. zabbix配置邮件告警

    1.安装邮件服务 yum -y install mailx @qq.com #发邮件测试 2.添加报警媒介 输入接收告警邮件的邮箱 3.配置SMTP服务端 使用本机作为SMTP服务器 4.创建触发器 ...

  5. 【shell实例】定时21:00-21:05,循环调用DSQL脚本,其它时段自动退出

    1.功能描述: 每日21:00定时调起test.sh,循环调起DSQL脚本test.dsql,直到21:05程序自动退出,捕获日志到相应log文件中. 2.日志文件: (1)日期.log文件中含Err ...

  6. RestTemplate 发送 get 请求使用误区 多个参数传值为null(转载)

    首先看一下官方文档是怎么描述的,传递多个值的情况(注意例子中用到的@pathParam,一般要用@queryParam) RestTemplate 实例 @Configuration public c ...

  7. Java设置session超时(失效)的时间

    在一般系统登录后,都会设置一个当前session失效的时间,以确保在用户长时间不与服务器交互,自动退出登录,销毁session具体设置的方法有三种:1.在web容器中设置(以tomcat为例)在tom ...

  8. 通过keepalived实现多主集群方案

    一. 环境说明:1.服务器列表:proxy01: eth0: 192.168.56.11 eth2: 192.168.156.11 proxy02: eth0: 192.168.56.12 eth2: ...

  9. Linux程序前台后台切换

    1.在Linux终端运行命令的时候,在命令末尾加上 & 符号,就可以让程序在后台运行 root@Ubuntu$ ./tcpserv01 & 2.如果程序正在前台运行,可以使用 Ctrl ...

  10. 一次jdk1.7升级jdk1.8后导致redis运行时blocked_clients过多问题解决

    公司有个采集项目,因为请求量较大,添加了redis集群,并且升级了原有的jdk1.7到jdk1.8版本,之后问题就出来了. 1.程序运行一段时间就自动停止,必须重启才能再次运行. 2.redis连接监 ...