最近在做的项目需要使用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. hibernate基本映射文件
  2. 神策数据加入猿团程序员大牛卡,创客大礼包助力开发。
  3. 电脑硬件检测_好用的电脑硬件型号有哪些_江西南昌顺同谦科技|电脑||笔记本|...
  4. 第五章、寻找满足条件的两个或多个数
  5. Django中celery配置总结
  6. 分析设计网上书店数据库,并画E-R图
  7. 2018年度人工智能优化商业运作的10大途径
  8. 游戏玩家场景高清桌面壁纸都是什么样的?
  9. Flex及AIR开发资源集合
  10. SQLite快速入门
  11. 10.UNIX 环境高级编程--信号
  12. 《Nature》 和 《 Science》 的区别是什么?
  13. 微信服务器小程序后台,微信小程序调用后台service教程详解
  14. MyBatis--逆向工程
  15. Arduino 工控板开发
  16. 2020同济大学电子与信息工程学院计算机系夏令营机试题目
  17. python链家数据分析统计服_Python数据分析实战-链家北京二手房价分析
  18. 艾美捷A型CpG DNA, 人/小鼠应用和化学性质说明
  19. uni-app小程序云开发函数——记录
  20. 计算机和管理结合,计算机应用技术与信息管理的结合

热门文章

  1. 超详细VMware安装CentOs图文教程
  2. ClientAbortException: java.io.IOException: Broken pipe 解决
  3. 后端数据校验之JSR303
  4. linux r服务安装失败,linux下R安装RMySQL不成功 configuration failed for package ‘RMySQL’...
  5. 功能近红外光谱成像技术在神经科学领域的临床应用
  6. 岛屿的最大面积--DFS(附搜索全家桶)
  7. 扁平脸逆袭“骨相美人”,毛戈平高光粉膏怎能缺席
  8. 打印如下图形 * * * * * * * * * * * * * * * * * * * * * * * * *
  9. Linux文件管理(一)系统目录结构
  10. 2023年产业基金研究报告