ガブリエレBiagini:
私は、以前のカフカの知識をしましたし、私は、メッセージングのための本当に堅実な選択肢と思われNats.ioで遊んでてきました。
特に、私は十分に文書化要求/応答メカニズムに興味があるが、私は正しくJnatsドライバとJavaでそれを実装する難しさを持っていました。
これは私のコネクターです。
// Single server nats connection
@PostConstruct
public void connect() throws ExternalServiceUnavailableException {
Options options = new Options.Builder()
.server(connectionString)
.maxReconnects(20)
.reconnectWait(Duration.ofSeconds(5))
.connectionTimeout(Duration.ofSeconds(5))
.connectionListener((conn, type) -> {
if (type == ConnectionListener.Events.CONNECTED) {
LOG.info("Connected to Nats Server");
} else if (type == ConnectionListener.Events.RECONNECTED) {
LOG.info("Reconnected to Nats Server");
} else if (type == ConnectionListener.Events.DISCONNECTED) {
LOG.error("Disconnected to Nats Server, reconnect attempt in seconds");
} else if (type == ConnectionListener.Events.CLOSED) {
LOG.info("Closed connection with Nats Server");
}
})
.build();
try {
connection = Nats.connect(options);
} catch (Exception e) {
LOG.error("Unable to connect to Nats Server");
throw new ExternalServiceUnavailableException(ExternalServiceUnavailableException.Service.NATS);
}
}
これは、(テスト目的のための非常に高いのawait時間)リクエストメソッドです。
public Optional<String> asyncRequest(String topic, String message) throws ExternalServiceUnavailableException {
Future<Message> reply = natsConnector.getConnection().request(topic, message.getBytes());
try {
Message msg = reply.get(10L, TimeUnit.SECONDS);
LOG.info(new String(msg.getData()));
return Optional.of(new String(msg.getData(), StandardCharsets.UTF_8));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
LOG.error("Unable to retrieve response for the sent request: " + message);
throw new ExternalServiceUnavailableException(ExternalServiceUnavailableException.Service.NATS);
}
}
そして、これは、応答メカニズムと応答ハンドラです。
@PostConstruct
private void init() {
Dispatcher dispatcher = natsConnector.getConnection().createDispatcher(message -> {
});
Subscription assetsInfo = dispatcher.subscribe("assets-info", message -> {
JSONObject requestMessage = new JSONObject(new String(message.getData(), StandardCharsets.UTF_8));
if (requestMessage.getString("requestType").equals("stock-status")) {
if (requestMessage.getString("of").equals("all")) {
JSONObject response = assetQuery.retrieveYesterdayStockStatus();
LOG.info("response ready");
natsOperation.publishEvent("assets-info", response);
LOG.info("message sent");
}
}
});
}
私の二つの独立したサービスは、dockerized Nats.ioを介して通信する、と私は正しくメッセージが同じトピックで両方のサービスによって送信されたことをたNats囲碁クライアント経由で確認することができます。
残念ながら、「リクエスタ」呼び出すには、asyncRequest
機能は非常に非常に高いのawaitでも、返信を処理しませんreply.get(...)
。
私は、評価しようとするとreply
、デバッグモードでのオブジェクトを、それと番組内の任意のデータを持っていませんTimeoutException
。
で、msg.getData()
プログラムがクラッシュ。
君たちは私のための任意のヒントを持っていますか?ありがとう!
コーリーヘーガーマン:
あなたは、元のメッセージからのreplyTo対象に発行するために、あなたの「replyer」のコードを変更する必要があります。
@PostConstruct
private void init() {
Dispatcher dispatcher = natsConnector.getConnection().createDispatcher(message -> {
});
Subscription assetsInfo = dispatcher.subscribe("assets-info", message -> {
JSONObject requestMessage = new JSONObject(new String(message.getData(), StandardCharsets.UTF_8));
if (requestMessage.getString("requestType").equals("stock-status")) {
if (requestMessage.getString("of").equals("all")) {
JSONObject response = assetQuery.retrieveYesterdayStockStatus();
LOG.info("response ready");
//See Change Here
natsOperation.publish(message.getReplyTo(), response);
LOG.info("message sent");
}
}
});
}
要求応答メカニズムは、生成されたreplyTo対象に単一の応答を探しています。