forked from mirror/MCSManager
新增 简单历史记录模式
This commit is contained in:
parent
47e495943b
commit
ac02231068
79
helper/LogHistory.js
Normal file
79
helper/LogHistory.js
Normal 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
|
||||
}
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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');
|
||||
// 退出监听实例,停止接受控制台信息
|
||||
|
@ -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');
|
||||
//刷新每个服务器的缓冲数据
|
||||
|
66
route/websocket/console/history.js
Normal file
66
route/websocket/console/history.js
Normal 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);
|
||||
|
||||
}
|
||||
});
|
@ -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, '服务器无法启动,建议检查配置或权限');
|
||||
|
Loading…
Reference in New Issue
Block a user