更多内容请点击 我的博客 查看,欢迎来访。
本教程基于《Django使用Channels实现WebSocket消息通知功能》
逻辑简述
xterm.js : 前端模拟 shell 终端的一个库,当用户每输入一个键,就向后端发送该数据
paramiko : Python 下对 ssh2 封装的一个库,可以使用他来远程连接主机
- 用户首先通过网页上的WebSocket连接到后端,后端再通过SSH连接到远程主机,实现一个长连接;
- 连接成功后, xterm.js 在浏览器中模拟shell终端,监听用户按键,将每次按键输入通过已连接好的WebSocket;
- 后端通过WebSocket收到数据后,将用户输入的内容通过 paramiko 建立的 SSH 通道连接到远程主机上执行;
- paramiko 将远程主机上的处理结果返回给后端;
- 后端将返回结果通过WebSocket返回用户页面;
- xterm.js 将从WebSocket接收的数据显示到到模拟终端中;
创建webssh app
创建app。名为webssh
将应用添加到 settings.py
INSTALLED_APPS = [
# 。。。。
'webssh.apps.WebsshConfig', # 网页远程ssh终端
]
修改应用下的 apps.py
from django.apps import AppConfig
class WebsshConfig(AppConfig):
name = 'webssh'
verbose_name = '远程终端'
修改应用下的 __init__.py
default_app_config = 'webssh.apps.WebsshConfig'
webssh逻辑代码
前端页面链接webssh
{% extends 'pxectrl/base-pxectrl.html' %}
{% load static %}
{% block title %}远程终端{% endblock %}
{% block css %}
<link href="{% static 'xterm/xterm.css' %}" rel="stylesheet">
<link href="{% static 'hadmin/css/plugins/toastr/toastr.min.css' %}" rel="stylesheet">
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins" id="id-box">
<div class="ibox-title">
<h5>在线终端</h5>
</div>
<div class="ibox-content" id="id-content">
<div class="row">
<form role="form" id="id-form" autocomplete="off">
<div class="col-md-4">
<div class="form-group">
<label>用户名</label>
<input type="text" placeholder="User" id="id-user" class="form-control"
autocomplete="off" value="user">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label>主机地址</label>
<input type="text" placeholder="Host" id="id-host" class="form-control" required
autocomplete="off" value="192.168.96.20">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label>端口</label>
<input type="text" placeholder="Port" id="id-port" class="form-control"
value="22" required autocomplete="off">
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<label>认证类型</label>
<label class="radio-inline">
<input type="radio" name="auth" id="id-use-pwd" value="pwd" checked> 密码认证
</label>
<label class="radio-inline">
<input type="radio" name="auth" id="id-use-key" value="key"> 秘钥认证
</label>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label id="id-auth-type">登录密码</label>
<input type="password" placeholder="Pwd" id="id-pwd" class="form-control"
required autocomplete="off" value="">
</div>
</div>
<div class="col-sm-6 hide" id="id-show-upload">
<div class="form-group">
<label>密钥文件</label>
<input class="filestyle" id="id-key-file" type="file">
</div>
</div>
<div class="col-sm-12">
注意:
<p style="color: red; font-size: 10px">1、当认证类型为密码认证时, 秘钥文件上传将不可用</p>
<p style="color: red; font-size: 10px">2、当认证类型为秘钥认证时, 如果密码输入框不为空,
则密码输入框的内容将作为秘钥的解密密码</p>
<button class="btn btn-sm btn-info" type="button" onclick="connectWebSocket()">
<strong>连接</strong>
</button>
</div>
</form>
</div>
<br>
<hr>
<br>
<table class="table table-striped">
<thead