【问题标题】:How to keep SSH connection available?如何保持 SSH 连接可用?
【发布时间】:2011-10-27 23:56:26
【问题描述】:

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

【问题讨论】:

  • 保持 ssh 连接处于活动状态与询问连接实例的存储位置并不完全相同。.. :-)
  • 你用的是什么框架?

标签: java ssh sshj


【解决方案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。您可以添加对多个连接的支持,即不同的主机和端口,只需将变量连接设为列表,然后检查主机和端口以获取正确的连接。您基本上创建了一个连接池,但对于客户端类来说,它看起来像是在创建连接。

【讨论】:

  • 所以代理模式的使用应该是这样的:用户点击连接后,我创建了 SSHConnection 类的实例,然后使用这个实例在 ConnectionProxy 类中设置连接字段,对吧?然后我在需要的地方创建 ConnectionProxy 的实例。当用户单击断开连接时,我关闭连接并将连接设置为空。
  • @Radek:在我的帖子中添加了一个示例。
【解决方案2】:

不管你把它放在哪里,只要你提供一个getter方法来检索它,并且那个获取方法是public

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-05-22
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 2018-07-28
      • 2020-04-12
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      相关资源
      最近更新 更多