新增 简单历史记录模式

This commit is contained in:
Suwings 2020-03-03 16:37:54 +08:00
parent 47e495943b
commit ac02231068
6 changed files with 228 additions and 21 deletions

79
helper/LogHistory.js Normal file
View File

@ -0,0 +1,79 @@
"use strict";
// 日志历史储存
const MAX_HISTORY_SIZE = 1000;
const DELETE_ALTER_INIT_SIZE = 600;
class LogHistory {
constructor(id) {
this.id = id;
this.readPoints = {};
this.log = new Array();
}
writeLine(text = "") {
if (text.length == 0) return;
if (this.log.length > MAX_HISTORY_SIZE) {
this.log.splice(0, DELETE_ALTER_INIT_SIZE);
}
let addLineLength = 0;
text = text.replace(/\r/igm, "");
if (text.indexOf('\n') != -1) {
let arr = text.split('\n');
for (let v of arr) {
if (v) {
this.log.push(v);
addLineLength++;
}
}
} else {
this.log.push(text);
addLineLength++;
}
for (let k in this.readPoints) {
this.readPoints[k] += addLineLength;
}
}
readLine(demander = "", size = 10) {
if (!this.readPoints[demander]) {
this.readPoints[demander] = 0;
}
let demanderPoint = this.readPoints[demander];
let text = "";
let logarr = this.log;
let i;
for (i = demanderPoint; i <= demanderPoint + size; i++) {
let point = logarr.length - i - 1;
if (point < 0) break;
let v = logarr[point] + '\n';
if (logarr[point].trim().length > 0) text += v;
}
this.readPoints[demander] = demanderPoint + size;
return text;
}
readLineReverse(demander = "", size = 10, notadd = false) {
if (!this.readPoints[demander]) {
this.readPoints[demander] = 0;
}
let demanderPoint = this.readPoints[demander];
let text = "";
let logarr = this.log;
let i;
for (i = (logarr.length - 1 - size - demanderPoint); i < logarr.length - demanderPoint; i++) {
let v = logarr[i] + '\n';
if (logarr[i].trim().length > 0) text += v;
}
if (!notadd) this.readPoints[demander] = demanderPoint + size;
return text;
}
setPoint(demander, v) {
this.readPoints[demander] = v;
}
}
module.exports = {
LogHistory
}

View File

@ -128,6 +128,14 @@
// 终端控制台界面,实时接受服务端终端日志
// 每当控制面板后端发送实时日志,都将第一时间触发此
MI.routeListener('server/console/ws', function (data) {
if (!VIEW_MODEL['Terminal']['isHistoryMode']) {
MCSERVER.term.write(data.body);
}
});
// 获取MC服务端终端日志历史记录
MI.routeListener('server/console/history', function (data) {
MCSERVER.term.write(data.body);
});

View File

@ -4,7 +4,7 @@
<div class="Panel PanelGray">
<div class="PanelBody">
<div class="row">
<div class="col-md-8" style="text-align: center;margin-top: 2px;">
<div class="col-md-7" style="text-align: center;margin-top: 2px;">
<div class="input-group input-group-sm">
<span class="input-group-addon">/</span>
<input type="text" id="" class="form-control" @keyup.up="toCommandhi(1)"
@ -13,20 +13,29 @@
aria-describedby="sizing-addon3">
</div>
</div>
<div class="col-md-4 PanelItemF" style="text-align: center;">
<div class="col-md-5 PanelItemF" style="text-align: center;">
<div class="PanelItem mb0"
v-on:click="RES.redirectPage('./template/component/console.html', 'server/console', MCSERVER.listenServername);">
<span class="glyphicon glyphicon-modal-window" aria-hidden="true"></span> 控制面板
<span class="glyphicon glyphicon-modal-window" aria-hidden="true"></span> 返回
</div>
<div class="PanelItem mb0" v-on:click="MCSERVER.term.startTerminal()">
<span class="glyphicon glyphicon-th-large " aria-hidden="true"></span> 清屏
</div>
<div class="PanelItem mb0" v-on:click="stopServer()">
<div class="PanelItem mb0" v-on:click="stopServer()" v-show="!isHistoryMode">
<span class="glyphicon glyphicon-pause" aria-hidden="true"></span> 关闭
</div>
<div class="PanelItem mb0" v-on:click="toOpenServer()">
<span class="glyphicon glyphicon-play PhoneDisplayNone" aria-hidden="true"></span> 开启
<div class="PanelItem mb0" v-on:click="toOpenServer()" v-show="!isHistoryMode">
<span class="glyphicon glyphicon-play" aria-hidden="true"></span>
开启
</div>
<div class="PanelItem mb0" v-on:click="loadHistory()" v-show="!isHistoryMode">
<span class="glyphicon glyphicon-facetime-video" aria-hidden="true"></span> 历史模式
</div>
<div class="PanelItem mb0" v-on:click="loadHistory()" v-show="isHistoryMode">
<span class="glyphicon glyphicon-console" aria-hidden="true"></span> 正常模式
</div>
<div class="PanelItem mb0" v-on:click="simpleLoadHistory()" v-show="isHistoryMode">
<span class="glyphicon glyphicon-play" aria-hidden="true"></span>
下一页
</div>
</div>
</div>
</div>
@ -62,7 +71,8 @@
disableStdin: true,
rows: rows,
cols: cols,
fontSize: fontSize
fontSize: fontSize,
convertEol: false
});
// 终端基本颜色代码
term.TERM_TEXT_RED = "\x1B[31m";
@ -94,8 +104,21 @@
// 监听此实例的标准输出,接下来将会有信息主动传来
WS.sendMsg('server/console/ws', PAGE.serverName);
// 加载此网页时立刻请求一次历史
WS.sendMsg('server/console/history_reverse', JSON.stringify({
serverName: PAGE.serverName
}));
VIEW_MODEL.newVue('Terminal', {
el: '#Terminal',
data: {
allowedStart: true,
command: '',
commandList: [],
commandListPrint: 0,
historyIf: false,
isHistoryMode: false
},
methods: {
toOpenServer: function () {
WS.sendMsg('server/console/open', PAGE.serverName);
@ -132,19 +155,35 @@
},
stopServer: function () {
this.toCommand('__stop__');
},
loadHistory: function (bool) {
if (!this.isHistoryMode) {
MCSERVER.term.clear();
// 加载下一页历史记录
WS.sendMsg('server/console/history', JSON.stringify({
serverName: PAGE.serverName
}));
this.isHistoryMode = true;
} else {
MCSERVER.term.startTerminal();
// 重置历史记录指针
WS.sendMsg('server/console/history_reset', JSON.stringify({
serverName: PAGE.serverName
}));
this.isHistoryMode = false;
}
},
simpleLoadHistory: function () {
WS.sendMsg('server/console/history', JSON.stringify({
serverName: PAGE.serverName
}));
}
},
data: {
allowedStart: true,
command: '',
commandList: [],
commandListPrint: 0,
historyIf: false
}
});
});
MI.rListener('onend', function () {
window.MCSERVER.term.clear();
// 终端窗口隐藏
$('#WebTerminalScreenWapper').css('display', 'none');
// 退出监听实例,停止接受控制台信息

View File

@ -49,6 +49,9 @@ serverModel.ServerManager().on('exit', (data) => {
selectWebsocket(data.serverName,
(socket) => response.wsMsgWindow(socket.ws, '服务器关闭'));
// 历史记录类释放
serverModel.ServerManager().getServer(data.serverName).logHistory = null;
// 传递服务器关闭事件
serverModel.ServerManager().emit("exit_next", data);
})
@ -77,8 +80,12 @@ WebSocketObserver().listener('server/console/ws', (data) => {
if (permssion.isCanServer(userName, serverName)) {
MCSERVER.log('[' + serverName + '] >>> 准许用户 ' + userName + ' 控制台监听');
//设置监听终端
// 设置监听终端
data.WsSession['console'] = serverName;
// 重置用户历史指针
const instanceLogHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (instanceLogHistory) instanceLogHistory.setPoint(userName, 0);
return;
}
@ -103,7 +110,9 @@ let consoleBuffer = {};
setInterval(() => {
for (const serverName in consoleBuffer) {
let data = consoleBuffer[serverName];
// 记录日志历史记录
serverModel.ServerManager().getServer(serverName).logHistory.writeLine(data);
// 发送前端的标准,前端只识别 \r\n ,不可是\n
data = data.replace(/\n/gim, '\r\n');
data = data.replace(/\r\r\n/gim, '\r\n');
//刷新每个服务器的缓冲数据

View File

@ -0,0 +1,66 @@
const {
WebSocketObserver
} = require('../../../model/WebSocketModel');
const permssion = require('../../../helper/Permission');
const serverModel = require('../../../model/ServerModel');
const response = require('../../../helper/Response');
// 正序历史记录路由
WebSocketObserver().listener('server/console/history', (data) => {
let userName = data.WsSession.username;
let bodyJson = JSON.parse(data.body);
let serverName = bodyJson['serverName'] || '';
if (permssion.isCanServer(userName, serverName)) {
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (!logHistory) {
response.wsSend(data.ws, 'server/console/history', 'terminalBack', "[控制面板]: 暂无任何历史记录.\r\n");
return;
}
let sendText = logHistory.readLine(userName, 30);
if (sendText) {
sendText = sendText.replace(/\n/gim, '\r\n');
sendText = sendText.replace(/\r\r\n/gim, '\r\n');
response.wsSend(data.ws, 'server/console/history', 'terminalBack', sendText);
} else {
response.wsSend(data.ws, 'server/console/history', 'terminalBack', "[控制面板]: 无法再读取更多的服务端日志.\r\n");
}
}
});
// 首次进入终端使用,倒序历史记录路由
WebSocketObserver().listener('server/console/history_reverse', (data) => {
let userName = data.WsSession.username;
let bodyJson = JSON.parse(data.body);
let serverName = bodyJson['serverName'] || '';
if (permssion.isCanServer(userName, serverName)) {
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (!logHistory)
return;
let sendText = logHistory.readLineReverse(userName, 50, true);
if (sendText) {
sendText = sendText.replace(/\n/gim, '\r\n');
sendText = sendText.replace(/\r\r\n/gim, '\r\n');
response.wsSend(data.ws, 'server/console/history', 'terminalBack', sendText);
}
}
});
// 历史指针重置路由
WebSocketObserver().listener('server/console/history_reset', (data) => {
let userName = data.WsSession.username;
let bodyJson = JSON.parse(data.body);
let serverName = bodyJson['serverName'] || '';
if (permssion.isCanServer(userName, serverName)) {
const logHistory = serverModel.ServerManager().getServer(serverName).logHistory;
if (!logHistory)
return;
logHistory.setPoint(userName, 0);
}
});

View File

@ -6,15 +6,21 @@ const {
WebSocketObserver
} = require('../../../model/WebSocketModel');
const mcPingProtocol = require('../../../helper/MCPingProtocol');
const { LogHistory } = require('../../../helper/LogHistory');
//开启服务器
WebSocketObserver().listener('server/console/open', (data) => {
let serverName = data.body.trim();
let userName = data.WsSession.username;
if (permssion.isCanServer(userName, serverName)) {
MCSERVER.log('用户 ', userName, ' 正在启动 ', serverName, ' 服务端实例...');
const serverInstance = serverModel.ServerManager().getServer(serverName);
if (!serverInstance) {
throw new Error("服务端实例不存在,这可能是恶意操作或误操作。");
}
// 为此服务端创建历史记录类
serverInstance.logHistory = new LogHistory(serverName);
try {
MCSERVER.log('用户 ', userName, ' 正在启动 ', serverName, ' 服务端实例...');
let retu = serverModel.startServer(serverName);
if (!retu) {
response.wsMsgWindow(data.ws, '服务器无法启动,建议检查配置或权限');