所以我做了一個小 api 來在螢屏上啟動 minecraft 服務器,效果很好。但是現在,每次我啟動或停止服務器時,api 都會以某種方式崩潰,因為 http 服務器在結束后寫入,我找不到任何結束服務器的東西。
我似乎無法找到它的結尾,這很奇怪。
我是 http 服務器、api 和這些東西的新手,所以這可能只是我的愚蠢錯誤。
//@author WizzerStudios on Github
//CC 2021
//Allowed:
//:: Editing
//Disallowed
//:: Redistributing
//:: Claiming as yours
//Importing stuff
var http = require('http');
const { exec } = require("child_process");
var url = require('url');
var https = require('https');
const fs = require('fs');
//Console log
console.log("Wizzer API booted.")
//Create API / HTTP Server
http.createServer(function (req, res) {
var q = url.parse(req.url, true).query;
//Check if password is correctly given.
if(q.password == "Password"){
//Switch to the action.
switch(q.action){
//If action is undefined:
case undefined:
res.end("Action not given.");
break;
//Get Logs is coming soon.
case "getlogs":
if(q.sname == undefined) res.end("No server name given.");
try {
const data = fs.readFileSync('serverfiles/' q.sname '/logs/latest.log', 'utf8');
res.end(data);
} catch (err) {
console.error(err)
res.end("Error occured! Server does not exist or isn't available.");
}
break;
//Start the server using the bash screen command.
case "stop":
//If no server name is given, end the connection.
if(q.sname == undefined) res.end("Server name not specified.");
//If server exists, run the screen command.
if (fs.existsSync('./servers/' q.sname '.json')) {
//Check if a screen session with the same name is already running.
exec('screen -S ' q.sname ' -Q select . ; echo $?',
(error, stdout, stderror) => {
if (error) {
console.error("Error: ", error);
return;
}
var out = stdout;
if(out.includes('0')){
exec('screen -p 0 -S minecraft-server -X eval `stuff "say TEST MESSAGE..."\\015`', (error, stdout, stderror) => {
res.end("Server stopped!"); //It says it stopped and crashes here !!!
});
} else {
res.end('Server already stopped!');
return;
}});
} else {
res.end("Server does not exist!");
return;
}
break;
case "start":
//If no server name is given, end the connection.
if(q.sname == undefined) res.end("Server name not specified.");
//If server exists, run the screen command.
if (fs.existsSync('./servers/' q.sname '.json')) {
//Check if a screen session with the same name is already running.
exec('screen -S ' q.sname ' -Q select . ; echo $?',
(error, stdout, stderror) => {
if (error) {
console.error("Error: ", error);
return;
}
var out = stdout;
if(out.includes('1')){
exec('screen -S ' q.sname ' -dm bash /home/mcserver/api/serverfiles/' q.sname '/start.sh', (error, stdout, stderror) => {
res.end("Server started!"); // Here it says it already stopped!
});
} else {
res.end('Server already started!');
return;
}});
} else {
res.end("Server does not exist!");
return;
}
break;
//Create server action.
case "createServer":
//If no game is given, end connection.
if(q.game == undefined) res.end("Game not given");
//Switch to the game chosen.
switch(q.game){
//Minecraft
case "minecraft":
if(q.sname == undefined) res.end("Server name not given."); // No server name given, end connection.
if(q.port == undefined) res.end("Port not given."); // No port given, end connection.
if(q.ram == undefined) res.end("Please give ram in gigabytes."); // No ram given, end connection.
if(q.software == undefined) res.end("Server software not given."); // Server software not given, end connection.
if(q.version == undefined) res.end("Server version not given."); // Version not given, end connection.
//Check if server already exists:
var path = './servers/' q.sname '.json';
if (fs.existsSync(path)) {
res.end("Server Exists.");
return;
}
ram = Number(q.ram);
ram *= 1024;
let server = {
name: q.sname,
port: q.port,
game: 'Minecraft',
ram: Number(ram),
software: q.software,
version: q.version
};
let data = JSON.stringify(server, null, 2);
fs.mkdir('./serverfiles/' q.sname, (err) => {
if (err) {
throw err;
res.end(err)
}
});
fs.writeFile('./serverfiles/' q.sname '/eula.txt', 'eula=true', function (err) {
if (err) res.end(err);
if(err) console.log(err);
});
fs.writeFile('./serverfiles/' q.sname '/start.sh', '#!/bin/bash\njava -Xmx' Number(ram) 'M ' '-Xms' Number(ram) 'M -jar /home/mcserver/api/serverfiles/' q.sname '/server.jar', function (err) {
if (err) res.end(err);
if(err) console.log(err);
});
exec('chmod x ./serverfiles/' q.sname '/start.sh');
fs.writeFile('./serverfiles/' q.sname '/server.properties', 'port=' q.port, function (err) {
if (err) res.end(err);
if(err) console.log(err);
});
try{
https.get("https://serverjars.com/api/fetchJar/" q.software "/" q.version, function(response) { response.pipe(fs.createWriteStream("serverfiles/" q.sname '/server.jar'))});
} catch(err){
res.end("Failed!")
console.log(err)
}
fs.writeFile("servers/" q.sname ".json", data, (err) => {});
res.write("Server Software: " q.software);
res.write("\nRam: " Number(ram));
res.write("\nServer name: " q.sname);
res.write("\nGame: Minecraft");
res.write("\nPort: " q.port);
res.end("\nVersion " q.version);
}
}
//if(req.url == "/?password=Password&?action=create"){
// res.write("game not given")
//} else if(req.url == "/?password=Password&?action=create&game"){
// res.write("Authenticated!")
//}
//} else {
//res.write("WRONG PASSWORD!")
}
res.end(); //end the response
}).listen(8080); //the server object listens on port 808
events.js:174
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at write_ (_http_outgoing.js:572:17)
at ServerResponse.write (_http_outgoing.js:567:10)
at exec (/home/mcserver/api/index.js:86:21)
at ChildProcess.exithandler (child_process.js:285:7)
at ChildProcess.emit (events.js:198:13)
at maybeClose (internal/child_process.js:982:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:259:5)
Emitted 'error' event at:
at writeAfterEndNT (_http_outgoing.js:634:7)
at process._tickCallback (internal/process/next_tick.js:63:19)
``` is the error.
I do know that i'm writing after the end, but where did it end?
Also, changing res.write to res.end doesn't crash my code, but it doesn't give anything in my browser.
uj5u.com熱心網友回復:
你必須檢查一下,以防你已經發送了一些回應,不要再發送一些東西。所以每個最好使用:
return res.end();
停止功能。
uj5u.com熱心網友回復:
取出以下行:
res.end(); //end the response <-----------------
}).listen(8080); //the server object listens on port 8080
您在函式內部呼叫了“res.end()”之后呼叫了它
res.end("\nVersion " q.version); // In createServer
呼叫它然后它退出 switch 陳述句并再次執行上面的 res.end()
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/332824.html
標籤:javascript 节点.js 接口 http 服务器
