如何保持SSH连接可用?

时间:2011-10-27 23:56:27

标签: java ssh sshj

我正在编写一个使用sshj库进行SSH连接的应用程序。用户从菜单中打开“连接对话框”,键入登录数据,然后单击“连接”按钮以建立连接。然后,用户从不同的面板和框架执行各种操作。我的问题是:在用户单击“断开连接”按钮之前,我应该在哪里保持此连接以使其可用于需要它的每个面板和框架?我在一些自定义类中考虑静态字段,但我不相信这样做。你有什么想法?

3 个答案:

答案 0 :(得分:1)

听起来你对某种类型的游泳池感兴趣。

您可以通过不同方式执行此操作。一种方法是拥有一个处理所有连接的类,这是一个单例。然后你只需要求池连接,例如

SSHConnection con = ConnectionPool.getConnection(host, port);

你也可以使用代理。在代理中,您实际上获得了占位符而不是实际连接。代理与其他实例共享信息,类似于

class ConnectionProxy {
    private static SSHConnection connection;
}

连接变量是共享的,当你创建一个新的ConnectionProxy时,你实际上会获得旧的连接,但看起来你得到一个新的连接。

另一种选择是简单地将实例传递给需要它的所有类。这将允许您跟踪谁做了什么,但您将失去从任何地方获得连接的灵活性。

如果你正在调试,传递一个实例会有所帮助,想一想这样。你在一个拥挤的房间,你有一些钱放在一个需要钥匙打开的盒子里。如果你把钥匙交给一个人(需要它的班级)并离开房间然后回来,钱就没了,你可以责怪那个人。如果你只是将钥匙留在盒子旁边的桌子上(实例是全局的)并离开房间,回来后钱就没了,那么祝你好运,找出谁拿走了它。

参考文献:
*] Proxy pattern - WikiPedia


代理示例

更具体地说,它看起来像这样:

public class ConnectionProxy implements Connectable {

    // where Connectable is some shared interface between ConnectionProxy
    // and SSHConnection. The proxy should "look like" a connection, it just
    // hides the actual connection behind the scenes.

    private static SSHConnection connection;

    public ConnectionProxy() { }

    public ConnectionProxy(String host, int port) {
        connection = new SSHConnection(host, port);
    }

    public void connect(String host, int port) {
        if (isConnected()) {
            return;
        }
        connection = new SSHConnection(host, port);
    }

    public void reconnect() {
        connection = new SSHConnection(connection.getHost(), connection.getPort());
    }

    public boolean isConnected() {
        return connection != null && connection.isConnected();
    }
}

您可以通过实例化或连接它来使用该类。

class Program {
    public void sendMessage() {
        ConnectionProxy proxy = new ConnectionProxy();
        if (!proxy.isConnected()) {
            // I guess noone connected it
            return;
        }
        proxy.sendBytes();
    }
 }

在连接对话框中,您实例化或连接ConnectionProxy。您可以添加对多个连接的支持,即不同的主机和端口,只需将变量连接改为列表,并检查主机和端口是否正确连接。您基本上创建了一个连接池,但是对于客户端类,它看起来就像是在创建连接。

答案 1 :(得分:0)

无论你把它放在哪里,只要你提供getter方法来检索它,并且获取方法是public

我认为这更像是逻辑上所属的问题。如果它是应用程序的属性(而不是窗口,框架,配置文件等等),则将getter放在主应用程序类中。

答案 2 :(得分:0)

设计方面,我建议将您可以通过SSH执行的操作包装在一个单独的类(RemoteCommands或其他类)中,并在需要的任何地方注入(设置为属性)此类的实例从。执行远程命令。

如果这看起来像很多额外的样板代码,因为每个框架和面板都需要它,这不应该对你说“我需要一个全局变量”。应该说“我应该减少直接执行远程命令的组件数量”。