最近在做的项目需要使用xterminal实现网页远程连接Linux终端,引了这个插件后发现问题很多,接下来一一记录问题所在。

一、如何在vue项目中使用xterm.js

  • 安装xterm.js,博主使用的是3.x
    npm i xterm --save
  • 在项目中引用
    • 新建组件Xterminal.vue
<template><div class="console" id="terminal'" v-loading="loading" element-loading-text="拼命连接中"></div>
</template>
<script>
import { Terminal } from "xterm";
import * as fit from "xterm/lib/addons/fit/fit";
import * as attach from "xterm/lib/addons/attach/attach";
import "xterm/dist/xterm.css";
Terminal.applyAddon(attach);
Terminal.applyAddon(fit);export default {name: "xterminal",data() {return {term: null,terminalSocket: null,copy: '',loading: true,cols: 80,content: ''};},methods: {runRealTerminal(res) {this.content.operate = 'connect';    // 根据后端需求调节建立连接时发送的数据this.terminalSocket.send(JSON.stringify(this.content));this.loading = false;console.log("webSocket is finished");},closeRealTerminal() {console.log("close");}},mounted() {let terminalContainer = document.getElementById("terminal");this.term = new Terminal({// 光标闪烁cursorBlink: true});this.term.open(terminalContainer, true);// open websocketthis.terminalSocket = new WebSocket("ws://********"); // 填入服务器的websocket连接地址this.terminalSocket.onopen = this.runRealTerminal;this.terminalSocket.onclose = this.closeRealTerminal;this.terminalSocket.onerror = this.errorRealTerminal;this.term.attach(this.terminalSocket);this.term._initialized = true;console.log("mounted is going on");this.term.on("data", (data) => {console.log("data", data);this.terminalSocket.send(JSON.stringify({operate: "command",command: data}));});},beforeDestroy() {this.terminalSocket.close();this.term.destroy();},
};
</script>
<style lang="scss">
</style>

以上代码是我对webssh的初步实现,当代码编译通过,在浏览器上展示时,博主发现终端窗口的大小并没有占满容器。


页面布局类似于上图。主要问题有以下几点:

  1. 终端的高度无法自适应容器大小
  2. 终端可显示区域未占满终端的100%宽度及高度
  3. 浏览器进行缩放或放大时无法自适应

针对这些问题,最初想到的办法是过去container的宽高,在初始化terminal时对cols及rows参数进行设置,但是container的高度只在终端初始化后才会被撑开,因此获取到的高度为0。最终想到的办法是获取浏览器的innerWidth和innerHeight,计算终端容器的宽高。如上图所示,终端的高度为 window.innerHeight - 140,宽度为window.innerWidth - 230px(只是举个例子)。之后初始化时进行设置,代码如下:

const width = window.innerWidth - 230;
const height = window.innerHeight - 140;
this.cols = parseInt(width/9, 10);     // 经过计算one col大约等同于9px
this.term = new Terminal({// 光标闪烁cursorBlink: true,cols: this.cols,rows: parseInt(height/17, 10),      // one row = 17px});

本以为到此开发结束,结果有一天心血来潮输入命令狂按a的时候,命令行过长不会换行而且把前面的内容覆盖了,淦!如下图所示。

百度了很多文章,却没有找到解决办法,转到github,在官方issue1359中找到了答案:

这只是第一种解决办法,删除term.fit()或者cols属性设置,但像他说的,这并不是一种好办法。


结合上面二者的回答原因是前后端设置的终端cols不同导致换行不正确。并且建议在设置cols后将其返回到后端,使后端设置成前端的cols。
所以博主在建立连接时,将cols也进行了传递,传递的方法很多,你可以在建立websocket连接时,将cols作为参数拼接到url后,而博主根据后端的需求将参数放在了content中进行了传递。

runRealTerminal(res) {this.content.operate = 'connect';this.content.cols = this.cols;this.terminalSocket.send(JSON.stringify(this.content));this.loading = false;console.log("webSocket is finished");},

之后确实实现了可换行的效果,但是问题又出现了,就是在浏览器缩放或放大的时候,终端内容消失了而且经常无法输入。这是因为没有使用fit()函数使其自适应。解决办法:在浏览器resize的时候调用fit函数。
在mounted钩子函数中加入:window.addEventListener('resize',this.windowChange);
在methods中定义:

windowChange(){const width = window.innerWidth - 230;const height = window.innerHeight - 140;this.cols = parseInt(width/9, 10);this.term.fit();this.term.resize(this.cols, parseInt(height/17, 10));this.term.scrollToBottom();}

同时需要向后端通过websocket发送最新的cols值。
至此,问题全部解决。end.

vue+xterm.js实现webssh踩坑之旅相关推荐

  1. vue中微信分享的踩坑之旅

    最近基于vue做一个h5的项目,里面涉及到微信分享,当时心里想着,这微信分享不是分分钟的事嘛,而且自己年初还做个一个项目,也实现了微信自定义分享,代码都是现成的,妥妥的放心. 上周二上午花了1个小时, ...

  2. vue中集成blockly的踩坑之旅

    blockly是一款可视化编辑器. blockly源码下载地址:https://gitee.com/mirrors/blockly?_from=gitee_search blockly的文档参考网址: ...

  3. python 同花顺thstrader_Python 踩坑之旅进程篇其三pgid是个什么鬼 (子进程\子孙进程无法kill 退出的解法)...

    代码示例支持 平台: Centos 6.3 Python: 2.7.14 1.1 踩坑案例 pid, ppid是大家比较常见的术语, 代表进程号,父进程号. 但pgid是个什么鬼? 了解pgid之前, ...

  4. 【个人笔记】vue+xterm.js+novnc实现终端交互和远程桌面

    介绍一个 VNC连接工具:iis7服务器管理工具 IIs7服务器管理工具可以批量连接并管理VNC服务器 作为服务器集成管理器,它最优秀的功能就是批量管理windows与linux系统服务器.vps.能 ...

  5. vue在微信里面的兼容问题_详解Vue微信公众号开发踩坑全记录

    本文介绍了Vue微信公众号开发踩坑全记录,分享给大家,也给自己留个笔记. 需求 微信授权登录(基于公众号的登录方案) 接入JS-SDK实现图片上传,分享等功能 现状及难点 采用的Vue框架,前后端分 ...

  6. Vue踩坑之旅(一)—— 数组、对象的监听

    作为一个接触 vue 才一个多月的小白,马上就接手基于 vue 的大型商城项目,其间真是跌跌撞撞踩了好多坑(o(╥﹏╥)o).在此写下自己的踩坑之旅,希望给跟我一样还在自学 vue 的同学一些帮助,另 ...

  7. 微信开发踩坑之旅 之 开发准备及服务器配置

    在工作和兴趣的机缘巧合之下,我开始接触微信开发.在这里简单记述自己的微信开发踩坑之旅. 首先,由于本人标准的理工科生,记述的语言有所不足,我尽量说明准确和详细点. 本文记述主线 ·申请公众号 ·公众号 ...

  8. VR制作中必须踩的坑365之037(oculus2、UE4、UE5、VR记录一年的踩坑之旅)Maya / ZBrush / Substance Painter倒来倒去

    VR制作中必须踩的坑365之037(oculus2.UE4.UE5.VR记录一年的踩坑之旅)Full 3D GAME ASSET workflow ( Maya / ZBrush / Substanc ...

  9. 重装win10系统+Ubuntu16.04的踩坑之旅(联想拯救者r720)

    重装win10系统+Ubuntu16.04的踩坑之旅(联想拯救者r720) 碎碎念:原本双系统用得很开心的,在手贱删了Ubuntu系统的某些隐藏文件之后导致Ubuntu系统不能正常使用,在某种程度强迫 ...

最新文章

  1. java多线程-死锁的一些问题
  2. 【整理】ABAP 7.40新特性介绍(上)
  3. python自动抓取指定信息_使用python自动转发抓取的网页信息
  4. reactjs Context的使用:一种组件间的通信方式
  5. mysql数据库从删库到跑路之mysq索引
  6. 马斯克:特斯拉FSD测试版V9将再推迟一周
  7. 2d shader unity 阴影_UNITY崩坏3角色渲染实践
  8. 电脑控制Android设备的软件——Total Control
  9. 谈表单的设计 (一) 合理对表单进行布局
  10. ngnix有版本要求吗_新版本探秘:比赛/活动等其他系统的新增与优化~
  11. umpy知识点补充:np.vstack()np.hstack()
  12. 快嘴企业名录搜索 2007 是什么
  13. ConstraintLayout约束布局
  14. 天地图key的申请步骤
  15. 合成冷色黑暗恐怖魔法师图片的PS教程
  16. 计算机的管理员在那,win10系统administrator管理员在哪
  17. imToken的创始人何斌:让区块链泛式革命在社区蔓延开来
  18. sdn网络搭建以及负载均衡
  19. idea中ctrl+shift+f(在文件中查找)失效,全图文解决方案
  20. 模式识别基本概念小结(学习笔记)

热门文章

  1. 怎样实现EDIUS中的视频快放的制作
  2. python题目及答案求三角形_Python练习题:星号三角形
  3. 黑鲨3pro手机如何升级鸿蒙5g系统,黑鲨 3 /黑鲨 3 Pro 到港:最平 5G 电竞手机上手测试!...
  4. 论文阅读及神经网络学习----Neural Networks for Multi-Instance Learning
  5. 高斯 到 正态分布 的前世今生
  6. 小红书数据分析:这个夏天,“围炉冰茶”继续刷屏
  7. 30岁从机械工程转行互联网,成为我做过最好的决定
  8. WorkBench安装教程
  9. Camera Tuning职业介绍
  10. Pyramid pooling module