Как сохранить доступное соединение SSH?

Я пишу приложение, которое использует библиотеку sshj для соединений SSH. Пользователь открывает Connect Dialog из меню, вводит данные для входа и нажимает кнопку Connect, чтобы установить соединение. Затем пользователь выполняет различные операции с разных панелей и фреймов. Мой вопрос: где я должен сохранить это соединение, чтобы сделать его доступным для каждой панели и фрейма, которые в нем нуждаются, пока пользователь не нажмет кнопку Отключить? Я думал о статическом поле в каком-то пользовательском классе, но я не убежден в этом. Какие у тебя идеи?

3 ответа

Решение

Похоже, вы заинтересованы в каком-то типе бассейна.

Вы можете сделать это по-разному. Одним из способов является создание класса, который обрабатывает все соединения, который является одноэлементным. Затем вы просто запрашиваете пул для соединения, например

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

Вы также можете использовать прокси для этого. В прокси вы фактически получаете заполнитель вместо фактического соединения. Прокси-сервер делится информацией с другими экземплярами, вроде как

class ConnectionProxy {
    private static SSHConnection connection;
}

переменная соединения является общей, и когда вы создаете новый ConnectionProxy, вы фактически получаете старое соединение, но похоже, что вы получаете новое соединение.

Другой вариант - просто передать экземпляр всем нуждающимся классам. Это позволит вам отслеживать, кто что делает, но при этом вы потеряете гибкость, позволяющую получить соединение откуда угодно.

Передача экземпляра поможет, если вы отлаживаете, подумайте об этом так. Вы находитесь в переполненной комнате, и у вас в ящике лежат деньги, для открытия которых нужен ключ. Если вы передадите этот ключ одному человеку (нуждающемуся в нем классу), выйдете из комнаты и вернетесь, а деньги уйдут, вы можете обвинить этого человека. Если вместо этого вы просто оставляете ключ на столе рядом с коробкой (экземпляр является глобальным) и выходите из комнаты, возвращаетесь и деньги исчезают, тогда удачи вам выяснить, кто их забрал.

Рекомендации:
*] Шаблон прокси - 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 или подключаете его. Вы можете добавить поддержку нескольких соединений, то есть разных хостов и портов, просто сделав вместо этого переменное соединение списком и проверив правильность соединения для хоста и порта. Вы в основном создаете пул соединений, но для клиентского класса это выглядит так, как будто оно создает соединение.

В плане дизайна я бы рекомендовал обернуть операции, которые вы можете выполнять над SSH, в отдельный класс (RemoteCommands или что-то подобное) и внедрение (установка в качестве свойства) экземпляра этого класса везде, где необходимо выполнить удаленную команду.

Если это кажется большим дополнительным кодом, потому что он нужен каждому отдельному кадру и панели, это не должно означать, что вам нужна глобальная переменная. Следует сказать: "Я должен уменьшить количество компонентов, которые непосредственно выполняют удаленные команды".

Неважно, где вы положили его, если вы предоставляете getter метод для его получения, и этот метод получения public,

Я думаю, что это больше вопрос о том, где он логически принадлежит. Если это свойство приложения (в отличие от окна, фрейма, профиля и т. Д.), Поместите метод получения в основной класс приложения.

Другие вопросы по тегам