实时保存后台服务的脚本

This commit is contained in:
fofolee 2022-05-02 16:56:44 +08:00
parent 64e585a7e5
commit a53c1a16e0
3 changed files with 86 additions and 96 deletions

View File

@ -534,8 +534,8 @@ window.runCodeFile = (cmd, option, terminal, callback) => {
ext = option.ext, ext = option.ext,
charset = option.charset, charset = option.charset,
scptarg = option.scptarg || ""; scptarg = option.scptarg || "";
let script = getQuickcommandTempFile(ext, 'quickcommandTempScript') let script = getQuickcommandTempFile(ext, 'quickcommandTempScript');
// 批处理和 powershell 默认编码为 GBK, 解决批处理的换行问题 // 批处理和 powershell 默认编码为 GBK, 解决批处理的换行问题
if (charset.scriptCode) cmd = iconv.encode(cmd.replace(/\n/g, '\r\n'), charset.scriptCode); if (charset.scriptCode) cmd = iconv.encode(cmd.replace(/\n/g, '\r\n'), charset.scriptCode);
fs.writeFileSync(script, cmd); fs.writeFileSync(script, cmd);
// var argvs = [script] // var argvs = [script]
@ -543,7 +543,7 @@ window.runCodeFile = (cmd, option, terminal, callback) => {
// argvs = argv.split(' ') // argvs = argv.split(' ')
// argvs.push(script); // argvs.push(script);
// } // }
var child, cmdline let child, cmdline;
if (bin.slice(-7) == 'csc.exe') { if (bin.slice(-7) == 'csc.exe') {
cmdline = `${bin} ${argv} /out:"${script.slice(0, -2) + 'exe'}" "${script}" && "${script.slice(0, -2) + 'exe'}" ${scptarg}` cmdline = `${bin} ${argv} /out:"${script.slice(0, -2) + 'exe'}" "${script}" && "${script.slice(0, -2) + 'exe'}" ${scptarg}`
} else if (bin == 'gcc') { } else if (bin == 'gcc') {
@ -557,33 +557,34 @@ window.runCodeFile = (cmd, option, terminal, callback) => {
// 在终端中输出 // 在终端中输出
if (terminal) cmdline = getCommandToLaunchTerminal(cmdline) if (terminal) cmdline = getCommandToLaunchTerminal(cmdline)
child = child_process.spawn(cmdline, { child = child_process.spawn(cmdline, {
encoding: 'buffer', encoding: 'buffer',
shell: true shell: true
}) });
// var chunks = [], // var chunks = [],
// err_chunks = []; // err_chunks = [];
console.log('Running: ' + cmdline); console.log('Running: ' + cmdline);
child.stdout.on('data', chunk => { child.stdout.on('data', chunk => {
if (charset.outputCode) chunk = iconv.decode(chunk, charset.outputCode) if (charset.outputCode) chunk = iconv.decode(chunk, charset.outputCode);
callback(chunk.toString(), null) callback(chunk.toString(), null);
// chunks.push(chunk) // chunks.push(chunk)
}) });
child.stderr.on('data', stderr => { child.stderr.on('data', stderr => {
if (charset.outputCode) stderr = iconv.decode(stderr, charset.outputCode) if (charset.outputCode) stderr = iconv.decode(stderr, charset.outputCode);
callback(null, stderr.toString()) callback(null, stderr.toString());
// err_chunks.push(err_chunk) // err_chunks.push(err_chunk)
}) });
// child.on('close', code => { // child.on('close', code => {
// let stdout = chunks.join(""); // let stdout = chunks.join("");
// let stderr = err_chunks.join(""); // let stderr = err_chunks.join("");
// callback(stdout, stderr) // callback(stdout, stderr)
// }) // })
return child return child
} }
let httpServer const dbStorage = utools.dbStorage;
let httpServer;
window.quickcommandHttpServer = () => { window.quickcommandHttpServer = () => {
let run = (cmd = '', port = 33442) => { let run = (port = 33442) => {
let httpResponse = (res, code, result) => { let httpResponse = (res, code, result) => {
// 只收受一次 console.log接收后就关闭连接 // 只收受一次 console.log接收后就关闭连接
if (res.finished) return if (res.finished) return
@ -593,38 +594,39 @@ window.quickcommandHttpServer = () => {
if (result) res.write(result); if (result) res.write(result);
res.end(); res.end();
} }
let runUserCode = (res, cmd, userVars) => { let runUserCode = (res, userVars) => {
let cmd = dbStorage.getItem('cfg_serverCode');
// 不需要返回输出的提前关闭连接 // 不需要返回输出的提前关闭连接
if (!cmd.includes('console.log')) httpResponse(res, 200) if (!cmd.includes('console.log')) httpResponse(res, 200);
window.runCodeInSandbox(cmd, (stdout, stderr) => { window.runCodeInSandbox(cmd, (stdout, stderr) => {
// 错误返回 500 // 错误返回 500
if (stderr) return httpResponse(res, 500, stderr) if (stderr) return httpResponse(res, 500, stderr.join(" "));
return httpResponse(res, 200, stdout) return httpResponse(res, 200, stdout.join(" "));
}, userVars) }, userVars)
} }
httpServer = http.createServer() httpServer = http.createServer();
httpServer.on('request', (req, res) => { httpServer.on('request', (req, res) => {
if (req.method === 'GET') { if (req.method === 'GET') {
let parsedParams = _.cloneDeep(url.parse(req.url, true).query) let parsedParams = _.cloneDeep(url.parse(req.url, true).query);
runUserCode(res, cmd, parsedParams) runUserCode(res, parsedParams);
} else if (req.method === 'POST') { } else if (req.method === 'POST') {
let data = [] let data = [];
req.on('data', (chunk) => { req.on('data', (chunk) => {
data.push(chunk) data.push(chunk);
}) })
req.on('end', () => { req.on('end', () => {
let parsedParams let parsedParams;
let params = data.join("").toString() let params = data.join("").toString();
// 先尝试作为 json 解析 // 先尝试作为 json 解析
try { try {
parsedParams = JSON.parse(params) parsedParams = JSON.parse(params);
} catch (error) { } catch (error) {
parsedParams = _.cloneDeep(url.parse('?' + params, true).query) parsedParams = _.cloneDeep(url.parse('?' + params, true).query);
} }
runUserCode(res, cmd, parsedParams) runUserCode(res, parsedParams);
}) })
} else { } else {
httpResponse(res, 405) httpResponse(res, 405);
} }
}) })
httpServer.listen(port, 'localhost'); httpServer.listen(port, 'localhost');

View File

@ -6,10 +6,9 @@
ref="editor" ref="editor"
@typing=" @typing="
(val) => { (val) => {
if ($root.profile.quickFeatures.apiServer.cmd !== val) { if (cmd === val) return;
$root.profile.quickFeatures.apiServer.cmd = val; cmd = val;
} saveCode();
restartServer();
} }
" "
:style="{ :style="{
@ -40,35 +39,34 @@
<q-btn-group unelevated> <q-btn-group unelevated>
<q-btn flat color="primary" icon="help" @click="showHelp" /> <q-btn flat color="primary" icon="help" @click="showHelp" />
<q-separator inset vertical /> <q-separator inset vertical />
<q-btn <div v-if="!!saveCodeTimer">
flat <q-btn
color="negative" flat
icon="stop" color="warning"
v-if=" icon="restart_alt"
$root.profile.quickFeatures.apiServer.serverStatus && !restartTimer @click="saveCode"
" label="正在保存"
@click="stopServer" />
label="停止服务" </div>
/> <div v-else>
<q-btn <q-btn
flat flat
color="warning" color="negative"
icon="restart_alt" icon="stop"
v-else-if=" v-if="$root.profile.quickFeatures.apiServer.serverStatus"
$root.profile.quickFeatures.apiServer.serverStatus && !!restartTimer @click="stopServer"
" label="停止服务"
@click="restartServer" />
label="正在重载" <q-btn
/> flat
<q-btn color="primary"
flat icon="play_arrow"
color="primary" v-else
icon="play_arrow" label="开启服务"
v-else @click="enableServer"
label="开启服务" >
@click="enableServer" </q-btn>
> </div>
</q-btn>
</q-btn-group> </q-btn-group>
</div> </div>
</div> </div>
@ -82,32 +80,30 @@ export default {
data() { data() {
return { return {
bottomHeight: 40, bottomHeight: 40,
restartTimer: null, saveCodeTimer: null,
cmd: null,
}; };
}, },
mounted() { mounted() {
this.$refs.editor.setEditorValue( this.cmd =
this.$root.profile.quickFeatures.apiServer.cmd this.$root.utools.whole.dbStorage.getItem("cfg_serverCode") || "";
); this.$refs.editor.setEditorValue(this.cmd);
this.$refs.editor.setEditorLanguage("javascript"); this.$refs.editor.setEditorLanguage("javascript");
this.restartTimer = null;
}, },
methods: { methods: {
enableServer() { enableServer() {
if (!this.cmd)
return quickcommand.showMessageBox("脚本不能为空!", "warning");
quickcommand quickcommand
.showConfirmBox( .showConfirmBox(
"请注意,该接口未做任何权限鉴定,千万不要试图将本端口转发出去,否则无异于将本机的 shell 权限暴露在公网!", "请注意,该接口未做任何权限鉴定,千万不要试图将本端口转发出去,否则无异于将本机的 shell 权限暴露在公网!",
"FBI WARNING" "FBI WARNING"
) )
.then((ok) => { .then(() => {
if (!ok) return;
this.$root.profile.quickFeatures.apiServer.serverStatus = true; this.$root.profile.quickFeatures.apiServer.serverStatus = true;
window window
.quickcommandHttpServer() .quickcommandHttpServer()
.run( .run(this.$root.profile.quickFeatures.apiServer.port);
this.$root.profile.quickFeatures.apiServer.cmd,
this.$root.profile.quickFeatures.apiServer.port
);
quickcommand.showMessageBox("启动服务成功!"); quickcommand.showMessageBox("启动服务成功!");
}); });
}, },
@ -116,18 +112,11 @@ export default {
this.$root.profile.quickFeatures.apiServer.serverStatus = false; this.$root.profile.quickFeatures.apiServer.serverStatus = false;
quickcommand.showMessageBox("关闭服务成功!"); quickcommand.showMessageBox("关闭服务成功!");
}, },
restartServer() { saveCode() {
if (!this.$root.profile.quickFeatures.apiServer.serverStatus) return; clearTimeout(this.saveCodeTimer);
clearTimeout(this.restartTimer); this.saveCodeTimer = setTimeout(() => {
this.restartTimer = setTimeout(() => { this.$root.utools.whole.dbStorage.setItem("cfg_serverCode", this.cmd);
window.quickcommandHttpServer().stop(); this.saveCodeTimer = null;
window
.quickcommandHttpServer()
.run(
this.$root.profile.quickFeatures.apiServer.cmd,
this.$root.profile.quickFeatures.apiServer.port
);
this.restartTimer = null;
}, 1000); }, 1000);
}, },
showHelp() { showHelp() {

View File

@ -22,7 +22,6 @@ export default {
apiServer: { apiServer: {
enable: false, enable: false,
port: 33442, port: 33442,
cmd: "",
serverStatus: false serverStatus: false
} }
} }