vue中web-shell简单实现

原理

客户端使用xterm.js展示命令行,服务端使用ssh2.js连接服务器,服务端与客户端通过sock进行通信

23

版本

相关代码

https://github.com/blogwy/vue-web-shell

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 初始化Terminal
const term = new Terminal({ cursorBlink: true })
term.open(document.getElementById('terminal'))
term.fit()
// 启动socket服务
const socket = openSocket('http://192.168.1.105:3100/ssh')

socket.on('connect', () => {
console.log('---连接成功---')
console.log(`---socket.id:${socket.id}---`)
socket.emit('init_data', { ip: '000.0.000.00', username: 'root', password: '00000' })
})
// 监听Terminal输入,把输入命令通过socket发送到服务端
term.on('data', res => {
socket.emit('ssh_client_data', res)
})
// 监听服务端返回的命令运行结果,显示到Terminal中
socket.on('ssh_server_data', res => {
term.write(res)
})

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const sshNamespace = io.of('/ssh')
const SSHClient = require('ssh2').Client;
const ssh = new SSHClient();
const utf8 = require('utf8');

sshNamespace.on('connection', socket => {
console.log('socket.id:', socket.id)
socket.on('init_data', res => {
console.log(res)
// 拿到ip数据,初始化连接
initSSH(socket, res)
})
})

http.listen(3100, () => {
console.log('listening on http://localhost:3100');
});

function initSSH (socket, config) {
console.log(config)
ssh.on('ready', () => {
ssh.shell((err, stream) => {
if (err) {
socket.emit('shell_error', '\r\n*** SSH SHELL ERROR: ' + err.message + ' ***\r\n');
}
// 监听客户端发送的命令
socket.on('ssh_client_data', data => {
stream.write(data);
});
// 监听返回结果并emit到客户端
stream.on('data', d => {
socket.emit('ssh_server_data', utf8.decode(d.toString('binary')));
}).on('close', () => {
console.log('close');
ssh.end();
});
});
}).on('close', () => {
socket.emit('connect_closed', '\r\n*** SSH CONNECTION CLOSED ***\r\n');
}).on('error', err => {
console.log(err);
socket.emit('connect_error', '\r\n*** SSH CONNECTION ERROR: ' + err.message + ' ***\r\n');
}).connect({
host: config.ip,
port: 22,
username: config.username,
password: config.password
});
}