如何在Node.js中向同进程启动的Minecraft服务器发送命令?
问题:Node.js无法向启动的Minecraft服务器进程发送命令
我通过Node.js启动Minecraft服务器,现有代码可通过GET请求/start启动服务器、捕获输出并写入文件,但新增的/mcstop接口尝试发送/stop命令时,无法作用于同一服务器进程。
原启动代码
const { spawn } = require('node:child_process') const express = require('express'); const bodyParser = require('body-parser'); const app = express(); const fs = require('fs'); app.get('/start', (req, res) => { fs.writeFile('minecraftstatus.txt', 'on', (err) => { if (err) throw err; }); const command = spawn('java', ['-jar', '-Xms2048M','-Xmx2048M', '-Dfile.encoding=utf8', 'server.jar', 'nogui']) command.stdout.on('data', output => { fs.appendFile('console.txt', ("\n" + output.toString()), 'utf-8', err => { console.log(err) }) console.log("Output: ", output.toString()) }) res.status(200).send("OK") }); app.listen(80, () => { console.log('Server started on port 80'); });
无效的命令发送尝试
app.get('/mcstop', (req, res) => { try { const command2 = spawn('/stop') command2.stdout.on('data', output => { console.log("Output: ", output.toString()) }) res.status(200).send("OK") } catch { console.log("Oh no...") } });
解决方案
问题根源
/start路由内的command是局部变量,/mcstop无法访问到这个Minecraft进程实例;- 错误地用
spawn('/stop')新建了完全无关的进程——Minecraft服务器是通过自身标准输入接收控制台命令的,并非通过外部调用/stop命令。
修改方案
- 将进程实例变量提升到全局作用域,让所有路由共享;
- 通过进程的
stdin写入命令(需加换行符模拟控制台回车操作); - 添加进程运行状态判断,避免重复启动或向不存在的进程发送命令。
修改后的完整代码
const { spawn } = require('node:child_process') const express = require('express'); const bodyParser = require('body-parser'); const app = express(); const fs = require('fs'); // 全局变量存储Minecraft进程实例 let minecraftProcess = null; app.get('/start', (req, res) => { // 检查是否已有运行中的进程 if (minecraftProcess) { return res.status(400).send("服务器已在运行"); } fs.writeFile('minecraftstatus.txt', 'on', (err) => { if (err) throw err; }); minecraftProcess = spawn('java', ['-jar', '-Xms2048M','-Xmx2048M', '-Dfile.encoding=utf8', 'server.jar', 'nogui']) minecraftProcess.stdout.on('data', output => { fs.appendFile('console.txt', ("\n" + output.toString()), 'utf-8', err => { if (err) console.log(err) }) console.log("Output: ", output.toString()) }) // 监听进程退出事件,清空全局变量并更新状态文件 minecraftProcess.on('exit', () => { minecraftProcess = null; fs.writeFile('minecraftstatus.txt', 'off', (err) => { if (err) console.log(err) }); console.log("Minecraft服务器已退出"); }) res.status(200).send("OK") }); app.get('/mcstop', (req, res) => { if (!minecraftProcess) { return res.status(400).send("没有运行中的服务器进程"); } // 向Minecraft进程的标准输入发送停止命令,需加换行符模拟回车 minecraftProcess.stdin.write('/stop\n'); res.status(200).send("已发送停止命令"); }); app.listen(80, () => { console.log('Server started on port 80'); });
内容的提问来源于stack exchange,提问作者opc
相关产品推荐
相关产品推荐

