vue和xterm.js和websocket以及ws心跳(防止ws长时间搁置断开连接)
npm install --save xterm-addon-fitnpm install --save xterm<template><div class="box"><div id="xterm"></div></div></template><script>import { Terminal } from "
·
npm install --save xterm-addon-fit
npm install --save xterm
<template>
<div class="box">
<div id="xterm"></div>
</div>
</template>
<script>
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
import "xterm/css/xterm.css";
import "xterm/lib/xterm.js";
export default {
data() {
return {
term: null,
socket: "",
WebSocketUrl: "",//ws接口
// 心跳
lockReconnect: false, //是否真正建立连接
timeout: 28 * 1000, //30秒一次心跳
timeoutObj: null, //心跳心跳倒计时
serverTimeoutObj: null, //心跳倒计时
timeoutnum: null, //断开 重连倒计时
};
},
mounted() {
this.init(this.WebSocketUrl);
},
//跑路前清除定时器
beforeDestroy() {
this.close();
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
clearTimeout(this.timeoutnum);
},
methods: {
// 心跳函数--------------
reconnect() {
//重新连接
var that = this;
if (that.lockReconnect) {
return;
}
that.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
that.timeoutnum && clearTimeout(that.timeoutnum);
that.timeoutnum = setTimeout(function () {
//新连接
that.init(that.WebSocketUrl);
that.lockReconnect = false;
}, 2000);
},
reset() {
//重置心跳
var that = this;
//清除时间
clearTimeout(that.timeoutObj);
clearTimeout(that.serverTimeoutObj);
//重启心跳
that.start();
},
start() {
//开启心跳
var self = this;
self.timeoutObj && clearTimeout(self.timeoutObj);
self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);
self.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
if (self.socket.readyState == 1) {
//如果连接正常
self.socket.send("ping");
} else {
//否则重连
self.reconnect();
}
self.serverTimeoutObj = setTimeout(function () {
//超时关闭
self.close();
}, self.timeout);
}, self.timeout);
},
//-----------------
initXterm() {
if (this.term) {
this.term.dispose();
}
this.term = new Terminal({
rendererType: "canvas", //渲染类型
rows: 35, //行数
convertEol: true, //启用时,光标将设置为下一行的开头
scrollback: 10, //终端中的回滚量
disableStdin: false, //是否应禁用输入
cursorStyle: "underline", //光标样式
cursorBlink: true, //光标闪烁
theme: {
foreground: "yellow", //字体
background: "#060101", //背景色
cursor: "help", //设置光标
},
});
this.term.open(document.getElementById("xterm"));
const fitAddon = new FitAddon();
this.term.loadAddon(fitAddon);
// 支持输入与粘贴方法
let _this = this; //一定要重新定义一个this,不然this指向会出问题
this.term.onData(function (key) {
//这里key值是你输入的值,数据格式order一定要找后端要!!!!
let order = {
data: key,
operation: "stdin",
};
_this.socket.onsend(JSON.stringify(order)); //转换为字符串
});
},
init(url) {
// 实例化socket
this.socket = new WebSocket(url);
// 监听socket连接
this.socket.onopen = this.open;
// 监听socket错误信息
this.socket.onerror = this.error;
// 监听socket消息
this.socket.onmessage = this.getMessage;
// 发送socket消息
this.socket.onsend = this.send;
},
open: function () {
console.log("socket连接成功");
this.initXterm();
//开启心跳
this.start();
},
error: function () {
console.log("连接错误");
//重连
this.reconnect();
},
close: function () {
this.socket.close();
console.log("socket已经关闭");
//重连
this.reconnect();
},
getMessage: function (msg) {
//msg是返回的数据
msg = JSON.parse(msg.data);
this.socket.send("ping");//有事没事ping一下,看看ws还活着没
//switch用于处理返回的数据,根据返回数据的格式去判断
switch (msg["operation"]) {
case "stdout":
this.term.write(msg["data"]);//这里write也许不是固定的,失败后找后端看一下该怎么往term里面write
break;
default:
console.error("Unexpected message type:", msg);//但是错误是固定的。。。。
}
//收到服务器信息,心跳重置
this.reset();
},
send: function (order) {
this.socket.send(order);
},
},
};
</script>
<style lang="scss" scoped>
.box {
width: 100%;
height: 100%;
#xterm {
width: 100%;
height: 100%;
}
}
</style>
不多bb,上图片
搁置情况下的ws心跳(不断刷ping,断开重连)
更多推荐
已为社区贡献2条内容
所有评论(0)