Вероятно, самое простое решение - свободно следовать по пути RMI.
Вы начинаете с интерфейса и реализации:
interface FooService {
Bar doThis( String param );
String doThat( Bar param );
}
class FooServiceImpl implements FooService {
...
}
Вы развертываете интерфейс с обеих сторон иреализация только на стороне сервера.
Затем, чтобы получить объект клиента, вы создаете динамический прокси.Его обработчик вызовов не будет делать ничего другого, кроме как сериализовать имя класса службы, имя метода и параметры и отправить его на сервер (изначально вы можете использовать ObjectOutputStream
, но вы можете использовать альтернативные методы сериализации, например, XStream).
Слушатель сервера принимает этот запрос и выполняет его, используя отражение, а затем отправляет ответ обратно.
Реализация довольно проста и прозрачна с обеих сторон, единственным серьезным предостережением является то, что ваши службы будутэффективно быть одиночками.
Я могу включить некоторые дополнительные детали реализации, если вам нужно, но это общая идея, которой я бы следовал, если бы мне пришлось реализовать что-то подобное.
Сказав это, яВозможно, пришлось бы поискать немного больше уже существующего решения, такого как веб-сервисы или что-то подобное.
Обновление: Это то, что будет делать обычный (локальный) обработчик вызовов.
class MyHandler implements InvocationHandler {
private Object serviceObject;
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(serviceObject, args);
}
}
Где serviceObject
- объект реализации вашего сервисак обработчику.
Это то, что вы должны разрезать пополам, и вместо вызова метода вам необходимо отправить на сервер следующее:
- Полное имяинтерфейс (или другое значение, однозначно идентифицирующее интерфейс службы)
- Название метода.
- Имена типов параметров, ожидаемых методом.
- The
args
массив.
Серверная сторона должна будет:
- Найти реализацию для этого интерфейса (самый простой способ - создать карту с ключамиимена интерфейсов и значения экземпляра синглтона реализации)
- Найдите метод, используя
Class.getMethod( name, paramTypes );
- Выполните метод, вызвав
method.invoke(serviceObject, args);
и отправив возвращаемое значение обратно.