原理 Link to heading

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

23

版本 Link to heading

相关代码 Link to heading

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

客户端 Link to heading

// 初始化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)
})

服务端 Link to heading

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
    });
}