WebSocketd是WebSocket的守护进程(命令行工具),负责处理WebSocket连接,并启动服务器应用程序来处理WebSockets,在应用程序和Web浏览器之间传递消息,无需任意依赖包且进程独立。WebSocketd是一款非常特别的WebSocket服务器,它的最大特点是后台脚本不限语言,其标准输入stdin就是WebSocket的输入,标准输出stdout就是WebSocket的输出。
WebSocketd本质上是命令行的WebSocket代理,只要在命令行可以执行的程序,都可以通过它与浏览器进行WebSocket通信。
官网:
安装:
下载:
wget https://github.com/joewalnes/websocketd/releases/download/v0.3.1/websocketd-0.3.1-linux_amd64.zip
unzip websocketd-0.3.1-linux_amd64.zip
环境变量:
解压后是一个二进制文件,将websocketd二进制复制到/usr/bin目录下即可。
简单示例:
1)shell脚本
#!/bin/bash
for ((COUNT = 1; COUNT <= 10; COUNT++)); do
echo $COUNT
sleep 1
done
2)启动websocketd:
chmod 777 count.sh
nohup websocketd --port=63800 ./count.sh >/dev/null 2>&1 &
3)浏览器测试:
var ws = new WebSocket('ws://192.168.18.12:63800/');
ws.onopen = function() {
console.log('CONNECT');
};
ws.onclose = function() {
console.log('DISCONNECT');
ws.close();
};
ws.onmessage = function(event) {
console.log('MESSAGE: ' + event.data);
};
打开chrome一个tab,F12进入开发模式,打开console,将上述代码输入进去即可。
4)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.close();
};
ws.onmessage = function(event) {
console.log('MESSAGE: ' + event.data);
};
</script>
</body>
</html>
客户端js可能会出现超时链接的,可以使用这个库ReconnectingWebSocket:https://github.com/joewalnes/reconnecting-websocket
分析:websocketd启动后会监听对应的websocket端口,当有客户端再次连接上时,websocketd会执行对应的shell脚本,并将每一步的标准输出作为消息发送到websocket通道。执行完shell脚本后,websocketd会断开本次连接,再次处于监听状态,当有请求到来会再次执行脚本...
说明:支持多client连接,每个client连接后,都将看到count.sh从头开始运行的过程数据(应该是独立的,每来一个请求,被包装的脚本从头运行)
注意:这里使用了一个shell脚本作为例子,其实我们可以将任何语言的程序(python、java...)输入给websocketd。详情见:https://github.com/joewalnes/websocketd/tree/master/examples
websocketd参数:
1)--staticdir:
staticdir表示允许WebSocketd作为静态文件提供,也就是说在当前项目指定通知执行的语言脚本同名的Web页面作为静态文件。
$ websocketd --staticdir=. --port=9501 ./test.sh
2)--devconsole:
devconsole标志会使内置的控制台WebSocketd与WebSocket端点进行手工交互。改参数主要是用来调试,调试带有交互功能的程序,手写js比较不方便,官方也给出了调试模式:https://github.com/joewalnes/websocketd/wiki/Developer-console
注:devconsole与staticdir不能不同使用,内置开发控制台旨在提供临时用户界面,用于构建真实的用户界面。
3)为websocketd配置nginx代理:
$ vim test.conf
server {
listen 443 ssl http2;
server_name www.test.com;
ssl_certificate /etc/test/full_chain.pem;
ssl_certificate_key /etc/test/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;
}
}
上面的例子是单向数据(服务端——>客户端),接下来看一个交互性更强的例子(greeter.py)
脚本
from sys import stdin, stdout
# For each line FOO received on STDIN, respond with "Hello FOO!".
while True:
line = stdin.readline().strip()
print('Hello %s!' % line)
stdout.flush() # Remember to flush
启动websocketd:
chmod +x count.py
websocketd --port=8080 ./greeter.py
前端html:
<!DOCTYPE html>
<head>
<title>websocketd test</title>
</head>
<body>
<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://localhost:8080/');
ws.onopen = function() {
log('CONNECT');
// input
ws.send("wwj");
};
ws.onclose = function() {
log('DISCONNECT');
ws.close();
};
ws.onmessage = function(event) {
log('MESSAGE: ' + event.data);
};
</script>
</body>
参考:
https://www.jianshu.com/p/385d2ecf718f
https://www.ruanyifeng.com/blog/2017/05/websocket.html