#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, я уверен, что она может соотнести ответ с запросом.