Можно ли использовать несколько объектов для связи RMI? - PullRequest
2 голосов
/ 15 сентября 2010

Сценарий:

  • Клиент C подключается к серверу S через RMI
  • C просит S создать обработчик H, S возвращает H к C
  • C, затемговорит с H

Теперь я могу сделать это двумя способами:

  • Сделать обработчик Remote и позволить S вернуть ему заглушку, чтобы C мог напрямуюпоговорите с ним (h.say(String msg);)
  • Дайте обработчику идентификатор и верните его C. C. будет говорить с H через S (s.sayToHandler(int id, String msg);)

Первое лучшеОо, а как же производительность?Будет ли открыто дополнительное TCP-соединение или используется существующее соединение между S и H?

Ответы [ 2 ]

2 голосов
/ 15 сентября 2010

Я не знаю о реализации.Я не думаю, что новое соединение установлено.Но то, что я знаю, это то, что чем больше объектов вы делите удаленно, тем больше объектов зависит от удаленной разыскивания для сбора мусора (поэтому будет больше объектов, живущих дольше, а не хорошо).

Альтернативный подход

Я рекомендую смешанный подход.Используйте хороший подход для клиента, но реализуйте его не так-то хорошо внутри:

interface Server {

  public Handler getHandler(...);
}

interface Handler extends Serializable {
  // it gets copied!
  public X doThis(...);
  public Y doThat(...);
}

class HandlerImpl implements Handler {
  public X doThis(...) {
    backDoor.doThis(this, ...);
  }
  public Y doThat(...) {
    backDoor.doThat(this, ...);
  }

  private BackDoor backDoor;
}

interface BackDoor {
  public X doThis(Handler h, ...);
  public Y doThat(Handler h, ...);
}

class ServerImpl imlpements Server, BackDoor {
  public Handler getHandler(...) {
    return /*a handler with a self reference as backdoor, only ONE remote obj shared via TWO interfaces */
  }
  ...
  // it does everything
  // it receives the handler
}

BackDoor и Handler являются синхронизированными интерфейсами.Первый имеет методы с Handler в качестве аргумента, второй имеет чистые методы.Я не думаю, что это имеет большое значение.А два разных интерфейса позволяют вам работать чисто, а клиент ничего не знает и позволяет тонкому сериализуемому обработчику выполнять грязную работу.

Надеюсь, вам понравится!

1 голос
/ 12 июня 2011

Спецификация RMI на самом деле не говорит, должно ли быть новое соединение или существующее повторно использовано. Проводной протокол допускает и то и другое, используя либо мультиплексирование , либо одно TCP-соединение на вызов (которое может быть повторно использовано для последующих вызовов одного и того же объекта-сервера, я не уверен). Если вам нужно туннелировать через HTTP, то разрешено только одно сообщение для каждого соединения.

Я не нашел ничего о том, как настроить тип используемого протокола (кроме отключения туннелирования HTTP).

Если вы хотите убедиться, что используется только одно TCP-соединение, используйте настраиваемые фабрики клиентских и серверных сокетов, выполняющие туннелирование нескольких соединений, хотя и самих себя. Вероятно, это будет менее эффективно, чем то, что будет делать система времени выполнения RMI.

...