2

我正在尝试为我的社区运行的一些服务器用 Java 编写一个简单的服务管理器。一般的想法是,服务器端应用程序启动服务器并通过 Process 类连接到其控制台的流,将其中继到可以通过 RDP 甚至远程在用户会话上运行的客户端应用程序。

现在,我的网络和中继工作正常;那东西相对简单。我遇到的问题是在服务器(或只是任务)重新启动时让服务器安全关闭。

我的印象是运行时的关闭钩子是处理这个问题的正确方法,但它们似乎不起作用。

我的控制台包装类的完整代码:http: //pastebin.com/vM3PQ9zE

这是启动服务的方法,为清楚起见添加了类字段:

private final ProcessBuilder builder;
private Process process;
private boolean stopped = false;
private HashSet<ConsoleListener> listeners;
private PrintStream commandStream;
private InputHandler handler;
private Thread shutdownTask;

public void start() throws IOException {
    if (this.hasStarted())
        throw new IllegalStateException(
                "This process has already been started once.");

    this.process = this.builder.start();

    for (ConsoleListener l : this.listeners) {
        l.onStart(new ConsoleEvent(this));
    }

    this.handler = new InputHandler(this.process.getInputStream());
    new Thread(this.handler).start();

    this.commandStream = new PrintStream(this.process.getOutputStream());

    Runtime.getRuntime().addShutdownHook(
            this.shutdownTask = new Thread(new ShutdownListener()));
}

类 ShutdownListener 内联定义为:

private class ShutdownListener implements Runnable {
    @Override
    public void run() {
        ConsoleApplication.this.nuke();
    }
}

nuke方法定义为:

public void nuke() {
    this.process.destroy();
}

现在我最终希望包装器能够发送正确的命令以安全关闭,但似乎它甚至无法强制关闭进程。我试过移动我的关闭挂钩,测试似乎表明 nuke() 从未被调用过。

任何帮助将不胜感激。

笔记:

我没有附加到任务计划程序。这似乎是处理服务器启动时最简单的方法。如果有不涉及任务计划程序的解决方案,我很想听听。

4

0 回答 0