修补正在运行的应用程序的简单、标准方法是什么?

问题描述 投票:0回答:1

给定一个在变量(即内存中状态和方法的集合)中定义应用程序的

index.js
脚本,您将如何确保运行脚本的调用在应用程序的现有实例上运行,而不是只是创建新实例吗?

例如,考虑这个仅定义计数器的应用程序,以及启动增量间隔、暂停间隔和读取当前计数的方法:

// ####################################################
// Define app
// ####################################################

const app = (() => {
    let counterInterval;
    let counter = 0;

    function startCounter() {
        counterInterval = setInterval(() => counter++, 1000);
    }

    function pauseCounter() {
        clearInterval(counterInterval);
    }

    function showCounter() {
        console.log(counter);
    }

    return {
        startCounter,
        pauseCounter,
        showCounter,
    }
})();

// ####################################################
// Run selected app method
// ####################################################

const argvs = process.argv.slice(2);
const [command, ...args] = argvs;

if (command === 'startCounter') {
    app.startCounter();
}

if (command === 'pauseCounter') {
    app.pauseCounter();
}

if (command === 'showCounter') {
    app.showCounter();
}

如果我运行

node ./index.js startCounter
,应用程序将运行并且终端将锁定到进程中。我怎样才能做到这一点:

  • 进程在后台运行;和
  • node ./index.js showCounter
    的后续调用会显示最初运行的应用程序内的计数器值(而不是创建新进程)?

在我看来,这个需求是一个很常见的用例,所以我认为 NodeJS 中一定有一种机制可以提供这种功能,但我找不到。我必须为此使用第三方工具包吗?

javascript node.js process
1个回答
0
投票

我的评论的解决方案。如前所述,您需要两个相互通信的进程。一个简单的方法是使用网络套接字。您没有说您正在使用什么操作系统。如果您使用 Windows,则需要调整网络创建/连接的内容。

index.js

const process = require("process");


process.env = Object.assign({
    DEAMON: "false",
    SOCKET: "/tmp/ipc-test.sock"
}, process.env);


console.log(`DAEMON: ${process.env.DEAMON}`)


if (process.env.DEAMON === "true") {
    require("./server.js");
} else {
    require("./client.js");
}

服务器.js

const net = require("net");
const fs = require("fs");


// cleanup previously used socket
try {
    fs.unlinkSync(process.env.SOCKET);
} catch (err) {
    if (err.code !== "ENOENT") {
        console.error(err);
    }
}

let counterInterval = null;
let counter = 0;

function startCounter() {
    counterInterval = setInterval(() => {
        counter++;
    }, 1000);
}

function pauseCounter() {
    clearInterval(counterInterval);
}


let server = net.createServer();
server.listen(process.env.SOCKET);

server.on("listening", () => {
    console.log(`listening on ${process.env.SOCKET}`)
});


server.on("connection", (client) => {

    console.log("Client connected");

    client.on("data", (data) => {

        let command = data.toString();
        console.log("Client send command:", command)

        if (command === 'startCounter') {

            startCounter();
            client.write("started");

        } else if (command === 'pauseCounter') {

            pauseCounter();
            client.write("paused");

        } else if (command === 'showCounter') {

            client.write(`${counter}`);

        } else {

            client.write(`command "${command}" is invalid`);

        }

    });

});

客户端.js

const net = require("net");

let [command] = process.argv.slice(2);
let socket = net.connect(process.env.SOCKET);

socket.once("data", (response) => {

    console.log(response.toString());
    socket.destroy();

});

// send command over unix socket
socket.write(command);

程序的概念很简单:使用

DAEMON=true node index.js
启动服务器/后台服务,并尝试向服务器发送命令
node index.js showCounter|startCounter|stopCounter|foo

当您运行服务器(

DEAMON=true nodemon index.js
)时,node.js 进程会创建一个网络套接字,并侦听可能连接的客户端。如果是这样,客户端发送命令,服务器执行该命令。 (开始计数器、停止计数器等...)

客户端部分也非常简单:它连接到网络套接字,并转发作为命令行参数传递的命令。当该命令未在服务器中实现时,它会响应“无效注释”。

非常简单直接。

© www.soinside.com 2019 - 2024. All rights reserved.