什么是webssh?
泛指一种技术可以在网页上实现一个 终端。从而无需 之类的模拟终端工具进行 连接,将 这一比较低层的操作也从 架构扭成了 架构 这样的架构常用在运维制作开发一些堡垒机等系统中,或是目前比较新型的在线教育方式,通过向学生提供一个可以直接使用浏览器进行相关 操作或代码编写的学习方式 主要是建立客户端与服务端的即时通信
模型
此种 实现方式,将通过结合 以及后端的 来进行实现,所需要的技术 栈如下
# 前端 vue websocket xterm.js
# 后端 django dwebsocket (channels) paramiko threading
技术介绍
xterm
前端通过xterm插件进行shell黑窗口环境的搭建,这个插件会自动解析由后台paramiko返回的带有标记样式的命令结果,并渲染到浏览器中,非常酷炫
websocket
这里通过websocket进行浏览器与django的数据交通桥梁
paramiko
paramiko此时的角色用来承担django与linux环境的交互,将前端发来的命令发送给后台,将 后台发来的命令结果返回到前端的xterm组件中
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import 'xterm/dist/xterm.css' // 看这里,添加xterm css文件样式 Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
使用xterm和websocket来实时发送命令
<template> <div class="console" id="terminal"></div> </template> <script> import { Terminal } from 'xterm' import * as attach from 'xterm/lib/addons/attach/attach' import * as fit from 'xterm/lib/addons/fit/fit' export default { name: 'webssh', data () { return { term: null, terminalSocket: null, order:'' } }, methods: { }, mounted () { //实例化一个websocket,用于和django江湖 this.terminalSocket = new WebSocket("ws://127.0.0.1:8000/web/"); //获取到后端传回的信息 this.terminalSocket.onmessage = (res) => { console.log(res.data); // var message = JSON.parse(res.data); //将传回来的数据显示在xterm里 this.term.writeln("\r\n"+res.data); //重置要发送的信息 this.order = "" //换行,显示下一个开头 this.term.write("\r\n$ "); } //ws连接的时候 // this.terminalSocket.onopen = function(){ // console.log('websocket is Connected...') // } //ws关闭的时候 // this.terminalSocket.onclose = function(){ // console.log('websocket is Closed...') // } //ws错误的时候 // this.terminalSocket.onerror = function(){ // console.log('damn Websocket is broken!') // } // this.term.attach(this.terminalSocket) // 绑定xterm到ws流中 }, let terminalContainer = document.getElementById('terminal') //创建xterm实例 this.term = new Terminal({ cursorBlink: true, // 显示光标 cursorStyle: "underline" // 光标样式 }) // 创建一个新的Terminal对象 this.term.open(terminalContainer) // 将term挂载到dom节点上 //在xterm上显示命令行提示 this.term.write('$ ') //监听xterm的键盘事件 this.term.on('key', (key, ev)=>{ // key是输入的字符 ev是键盘按键事件 console.log("key==========", ev.keyCode); this.term.write(key) // 将输入的字符打印到黑板中 if (ev.keyCode == 13) { // 输入回车 // console.log("输入回车") // this.term.write('$ ') // console.log(this.order) //使用webscoket将数据发送到django this.terminalSocket.send(this.order) // this.order='' console.log("里面的order",this.order) }else if(ev.keyCode == 8){//删除按钮 //截取字符串[0,lenth-1] this.order = this.order.substr(0,this.order.length-1) //清空当前一条的命令 this.term.write("\x1b[2K\r") //简化当前的新的命令显示上 this.term.write("$ "+this.order) console.log("截取的字符串"+this.order) typeof this.order }else{// 将每次输入的字符拼凑起来 this.order += key console.log("外面的order",this.order)} }) }, } </script>