Реализация RPC с базовым протоколом запроса / ответа (JSON-RPC на SIP)

#java #callback #sip #rpc

#java #обратный вызов #sip #rpc

Вопрос:

Посмотрите на следующий вариант использования.

У меня есть клиентское (Java) приложение, которое хочет получить / установить состояние другого удаленного приложения (C). Связь между ними осуществляется через SIP, который выполняется в другом потоке.

Интерфейс SIP может выполнять следующие действия:

SendMessage onRequest

У меня есть две идеи для архитектуры:

RPC (JSON-RPC)

Определите класс, который выполняет сортировку / отмену сортировки для JSONRPCRequests и JSONRPCResponse (http://software .dzhuvinov.com/json-rpc-2.0-base.html )

Определите класс вызывающего, который имеет что-то вроде метода вызова (сервер, имя, аргументы).

В классе Invoker имя и аргументы помещаются в JSONRPCRequest и отправляются через SIP-уровень SendMessage

Теперь возникает моя проблема. Как мне на самом деле вернуть права вызывающему абоненту? Теперь поток управления:

Вызывается метод onRequest, но теперь я знаю, является ли он ответом на мой предыдущий вызов. Что я делаю, так это помещаю все ответы, поступающие на мой сервер, в карту и просто опрашиваю этот список в вызывающем устройстве.

Грубый набросок может быть;

Вызывающий (предоставляет API клиенту)

 class Invoker {

    private Channel channel;

    public Invoker(Channel channel) { this.channel = channel; }

    public Object call(String server, String name, Object .. args) {
        JSONRPCRequest req = ...;
        channel.sendMessage(server, req.toString());
        while( ! channel.hasResponse(req.id()) {
            Thread.sleep(42);
        }
        return channel.getResponse(req.id()).result();        
    }

}
 

Канал (интерфейс для обмена сообщениями):

 class Channel {

    private Map<Object, JSONRPCResponse> responses = new //;

    private Sip sip = new Sip() {
        public void onRequest(String msg) {
            JSONRPCResponse response = JSONRPCResponse.parse(msg);
            responses.put(msg.id(), response);
        }
    };

    public void sendMessage(String server, String message) {
        sip.sendMessage();
    }

    public boolean hasResponse onRequest(Object id) {
        responses.hasKey(id);
    }

    public JSONRPCResponse getResponse(Object id) {
        responses.get(id);
        responses.delete(id);
    }

}
 

SIP (сам messenger):

 abstract class Sip {

    public void sendMessage(String msg) {
        // SIP magic
    }

    public abstract void onRequest(String msg);    
}
 

Есть ли лучший способ сделать это? Мои самые большие проблемы / запахи кода:

  • блокировка в вызывающем
  • протокол находится в Invoker, возможно, я хочу переключить сортировку на что-то другое
  • карта как средство получения правильного ответа на запрос
  • абстрактный метод SIP выглядит странно
  • Нет обработки ошибок
  • Нет тайм-аута

Передача сообщений

Есть ли простой способ избавиться от RPC и реализовать что-то вроде RPC с простой передачей сообщений? Любые подсказки для шаблона приветствуются. Мне не нужен сам код, меня вполне устраивает только архитектура. Я попытался найти в Google реализации передачи сообщений и то, как они на самом деле меняют состояние с его помощью, но я не нашел ничего полезного. Как реализовать обработку тайм-аута / ошибок?

Также приветствуются любые хорошие книги / литература по этой теме, поскольку я никогда не программировал такие распределенные материалы.

Любые другие идеи о том, какой протокол использовать внутри SIP для изменения состояния, также приветствуются, поскольку RPC был моей первоначальной мыслью, и я не нашел ничего другого полезного.

Я думаю, код не будет компилироваться, это было просто для визуализации моей идеи.

Ответ №1:

Определите интерфейс службы, который имеет значимые (для случая США) методы. Вместо использования блокирующих вызовов попросите клиента предоставить обработчик ответов, который будет вызван по завершении операции:

 interface ResponseHandler {
   void onComplete(Response response);
   void onError(Throwable error);
}

interface SomeService {
   void set(String attribute, Object value, ResponsHandler responseHandler);
   void get(String attribute, ResponseHandler responseHandler);
}
 

Реализация интерфейса сервиса может использовать любой подходящий протокол, но он должен сопоставлять запросы с ответами, чтобы вызывать правильные обратные вызовы.

Комментарии:

1. Одной из моих проблем было сопоставление сообщений запроса / ответа. Существует ли какая-либо стандартная процедура / шаблон или литература по этой теме, которую вы, возможно, знаете?

2. Все зависит от протокола. Если вы используете библиотеку SIP, такую как JAIN-SIP, я уверен, что она может соотнести ответ с запросом.