Web SSH 在线编程(一) --(HTML 页面实现终端(terminal) 模拟器远程连接)

目标实现效果:

  • 在页面实现Linux终端连接

所需工具:

  • Django,Linux,Vue
  • Xtrem.js
  • DWebSocket
  • paramiko
  • SSH

WebSSH在线编程工具介绍

首先我们需要 在页面的一个终端模拟器。
XTerm 就会解决这个,找到 vue 项目中的 package.json 文件
Web SSH 在线编程(一) --(HTML 页面实现终端(terminal) 模拟器远程连接)_第1张图片

在Node.js中,模块是一个库或框架,也是一个Node.js项目。Node.js项目遵循模块化的架构,当我们创建了一个Node.js项目,意味着创建了一个模块,这个模块的描述文件,被称为 package.json。

打开
Web SSH 在线编程(一) --(HTML 页面实现终端(terminal) 模拟器远程连接)_第2张图片
dependencies 下面填写 xterm 喝对应的版本号 我们这里用 3.1.0 的,然后删除 vue 的依赖包
在这里插入图片描述
删除后在执行 npm install 下载依赖、这里解释一下

dependencies:应用能够正常运行所依赖的包。用户在使用 npm install 安装你的包时会自动安装这些依赖。
详细版

创建 vue 页面

<template>
    <div 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'      // 窗口自适应

  Terminal.applyAddon(attach)  // 功能添加
  Terminal.applyAddon(fit)
    export default {
        name: "console.vue",
        mounted() {
            var terminalContainer = document.getElementById('terminal')
            this.term = new Terminal(this.terminal)   // 初始化终端
            this.term.open(terminalContainer)   // 将 div 绑定到初始化后的终端
            
        }
    }
</script>

<style scoped>

</style>

创建 终端展示的 DIV、引入终端 和 必要的两个功能、将功能插件添加到终端组件。然后 定义 mounted 钩子, 获取到 div 标签的 id,将 id 帮定到实例化好的 终端组件上、你也可以理解是 终端组件打开了 div

main.js 导入 需要的 CSS 样式

// main.js
import 'xterm/dist/xterm.css'

index.js 里面注册 这个 页面的路由、

import console from '@/components/console'

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [{
    path: '/console',
    name: 'console',
    component: console
  }
 ]
})

打开 页面 就会看到 终端的 黑窗口了
Web SSH 在线编程(一) --(HTML 页面实现终端(terminal) 模拟器远程连接)_第3张图片
下一步, 连接远程的 终端 Linux 也好 centos7 也好,这个时候我们要用到 WebSocket 进行连接 传递数据 到 Django。
还是在 mounted

// mounted
this.terminalSocket = new WebSocket('ws://127.0.0.1:8000/webssh/')   // 初始化 WebSocket 指定好向后代发送的地址 

this.term.attach(this.terminalSocket)     // 将 终端 附属到 WebSocket

初始化 的这一行代码 非常关键

ws 就是 WebSocket 的缩写 是遵循的 HTTP 协议,安全证书 HTTPS 对应的是 wss

WebSocket 的特点就是服务端可以主动向客户端推送消息,客户端也可以主动向服务端发送消息,实现了真正的平等。

引入 WebSocket、设置连接的端口、然后运用 attach 函数 附属、第一步 连接就做好了,连接之后 ,要写 最坏的打算, 比如 用户直接吧浏览器关闭了 连接也要 对应的断开。
这时 我们用 Vue 生命周期中的 beforeDestroy 钩子 来实现
想多了解的 vue生命周期钩子

// 和 mounted 同级
beforeDestroy() {
            this.terminalSocket.close()  // 关闭 WebSocket
            this.term.destroy()  // 关闭终端
        }

beforeDestroy(对象准备死掉)
就在Vue对象被破坏并从内存中释放之前, deforeDestroy 钩子被触发

此时,就代表着 Vue页面上的终端 发送 WebSocket 给 Django了, 再写一个路由 接收(此时 前后端的跨域都是解决好的

from django.urls import path, include
from online import views   # online 是我的子应用

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/', include('online.urls')),
    path('webssh/', views.WebSSH.as_view())  
    # 因为要实现的不是一个接口 视图响应的功能 所以 不写 as_view() 也是可以的
]

全部代码

<template>
    <div 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'      // 窗口自适应

  Terminal.applyAddon(attach)  // 功能添加
  Terminal.applyAddon(fit)
    export default {
        name: "console.vue",
        mounted() {
            var terminalContainer = document.getElementById('terminal')
            this.term = new Terminal(this.terminal)   // 初始化终端
            this.term.open(terminalContainer)   // 将 div 绑定到初始化后的终端

            this.terminalSocket = new WebSocket('ws://127.0.0.1:8000/webssh/')   // 初始化 WebSocket
            this.term.attach(this.terminalSocket)     // 将 终端 附属到 WebSocket
        },
        beforeDestroy() {
            this.terminalSocket.close()
            this.term.destroy()
            // beforeDestroy(对象准备死掉)
            // 就在Vue对象被破坏并从内存中释放之前, beforeDestroy 钩子被触发
        }
    }
</script>

<style scoped>

</style>

此时 前台 Vue 已经发送过来了 WebSocket, 后台 Django 接收 需要用到 dwebsocket

pip install dwebsocket

下载好之后 注册到 Django settings 的 INSTALLED_APPS里

# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'online',
    'rest_framework',
    # 'corsheaders',
    'djcelery',
    'dwebsocket' # 在这里
]

dwebsocket 提供了一个装饰器 @accept_websocket、它装饰的视图函数只会接收到 WebSocket 的请求 隔离了其他无用的 HTTP 链接。

# views.py
from dwebsocket import accept_websocket  # 引入

@accept_websocket     # 只接受 WebSocket 的 请求

def WebSSH(request):
    if request.is_websocket:
        pass

前台的 WebSocket 已经完全连接上 后台的 dwebsocket 了
就先这样先把视图模子写好,下一章 实现 页面操作 对应的 处理

未完待续…

你可能感兴趣的:(#,WebSocket)