先简单说一下原理吧,在网页上和服务器上建立一个ws连接,然后网页获取用户输入传给服务端,服务端解析用户输入,在服务端shell执行命令并将执行输出通过ws传给网页渲染到页面上。
以上原理说起来简单,但是完全自己实现是不太现实的。下面我把实现用到的库和插件以及使用方式简单说一下。
xterm.js
xterm.js
是一个用来实现网页上终端UI的库。
简单的使用示例:
<div id="terminal"></div>
<script>
var terminalIns = new Terminal();
terminalIns.open(document.getElementById('terminal'));
terminalIns.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')
</script>
node-pty
node-pty
是在node.js
上用户执行shell
命令,并获取标准输出的仓库,可以配合xterm.js
通过ws来实现远程终端。
var os = require('os');
var pty = require('node-pty');
var shell = os.platform() === 'win32' ? 'powershell.exe' : 'bash';
var ptyProcess = pty.spawn(shell, [], {
name: 'xterm-color',
cols: 80,
rows: 30,
cwd: process.env.HOME,
env: process.env
});
ptyProcess.on('data', function(data) {
process.stdout.write(data);
});
ptyProcess.write('ls\r');
ptyProcess.resize(100, 40);
ptyProcess.write('ls\r');
sockjs
sockjs
这个没啥好说的,实现WebSocket
的库。
const http = require('http');
const sockjs = require('sockjs');
const echo = sockjs.createServer({ prefix:'/echo' });
echo.on('connection', function(conn) {
conn.on('data', function(message) {
conn.write(message);
});
conn.on('close', function() {});
});
const server = http.createServer();
echo.attach(server);
server.listen(9999, '0.0.0.0');
实现流程
- 在服务端通过
sockjs
起一个ws的服务 - 并实例化
node-pty
通过sockjs
的ws服务来接受客户端的命令执行并将反馈通过ws输出到客户端 - 在网页端通过
xterm.js
初始化一个网页终端UI - 将网页端的
xterm.js
实例与服务端的node-pty
建立连接,这里需要用到xterm.js
的一个插件xterm-addon-attach
这个插件接受一个WebSocket
实例作为参数与服务端建立连接
code
一个完整的示例代码web-term ,有兴趣的可以看看。