首页 > 解决方案 > 如何在 Rust 中生成分离的命令/进程?

问题描述

我编写了一个小的可执行文件来为 Node 开发环境启动一个 WebSocket 服务器。

在一个单独的 NodeJS 应用程序(在 Electron 中运行)中,我child_process.spawn()用来运行二进制文件并在应用程序启动时启动服务器。

该服务器子进程劫持了节点child_process生成的命令并且不退出,因此我无法捕获退出代码或处理故障。我只需要知道它开始或没有开始。

如何在 Rust 中启动这个过程,以便我可以退出(成功、失败等)并且孩子继续运行?

我的相关部分main.rs

extern crate ws;

use std::env;
use std::process::Command;
use ws::{connect, CloseCode};

fn main() {
    let args: Vec<String> = env::args().collect();
    let command = &args[1];
    if command == "activate" {
        println!("Activating");
        stop_server_process();
        start_server_process();
    }
}

fn start_server_process() {
    let mut command;
    if cfg!(windows) {
        command = Command::new(".\\node_modules\\.bin\\ws.cmd");
    } else {
        command = Command::new("./node_modules/.bin/ws");
    }
    command.arg("--websocket");
    command.arg("test/mock-api/ws-server.js");
    command.arg("-p");
    command.arg("9401");
    match command.spawn() {
        Ok(child) => println!("Server process id is {}", child.id()),
        Err(e) => {
            println!("Server didn't start: {}", e);
            std::process::exit(1);
        },
    }
    std::process::exit(0);
}

fn stop_server_process() {
    connect("ws://localhost:9401", |out| {
        out.send("server-stop").unwrap();
        move |msg| {
            println!("Got message: {}", msg);
            out.close(CloseCode::Normal)
        }
    }).unwrap()
}

我正在从我的 Electron 应用程序运行二进制文件,如下所示:

/**
 * @return {Promise<Boolean>}
 */
static activate() {
  return new Promise((resolve, reject) => {
    const command = spawn(process.env.SERVER_LOCAL_PATH, ['activate']);
    command.stdout.on('data', (data) => {
      console.log(`stdout: ${data}`);
    });
    command.stderr.on('data', (data) => {
      console.log(`stderr: ${data}`);
    });
    command.on('close', code => resolve(code === 0));
    command.on('error', error => reject(error));
  });
}

这永远不会解决,因为wswebsocket 开始运行并且生成的进程现在正在从中获取事件。我的控制台输出如下:

stdout: Activating <--- Rust binary output
Server process id is 78057 <--- Rust binary output
stderr: Serving at [various URL variations] <--- ws binary output
stdout: Client Connected <--- ws binary output

WebSocket 服务器基于此库中的示例和代码。这是它的可复制版本:

module.exports = SocketBase => class Socket extends SocketBase {
  websocket(wss) {
    wss.on('connection', (ws) => {
      console.log('Client Connected');
      ws.on('message', (data) => {
        if (data === 'server-stop') {
          console.log('Stopping...');
          process.exit(0);
        }
        // do some faked JSON response data
      });
      ws.on('close', () => {
        console.log('Client Disconnected');
      });
      ws.on('error', (error) => {
        console.log(error.toString());
      });
    });
  }
};

标签: processrust

解决方案


推荐阅读