私はサーバーと非同期で通信するSpring CLIアプリケーションを構築しました。サーバーは与えられた、私はそれを作成していない、基本的に私のアプリケーションは、TCPソケットを開いて、それを介してJSONを送信する必要がありますし、JSONを返します。 CLIパラメータを使用しないことが必須ですが、要求のコールバックでは、CLIに対応する番号を挿入して選択する必要があるオプションのセットをユーザーに表示します。コマンドを入力するとコンソールに表示される(これは予想される動作です)、何かを押すまで非同期コールバックをブロックします(何も表示されない場合はCLIに何も表示されません)。私が束を押していない限りコールバック - これは予期せぬことです)。コンソールから読み込むには、JLineのコマンドラインを使用しましたが、私が達成したいのは、サーバーからの応答を取得し、コールバックが提供されると、コールバックが実行されているスレッドにコンソールが与えられます。コールバックの内容を直ちにコンソールに出力し、何もせずに入力を読み取ることができます)。JavaのSpring CLIでの非同期IO処理方法は?
いくつかのコード:次に
public void runReceiver(){
receiverThread = new Thread(() -> {
byte[] digit = null;
int nb;
Iterator<CommandListener> it;
CommandListener listener;
String message;
List<CommandListener> listenersToRemove = new ArrayList<>();
while (true) {
try {
nb = communicatorInput.readInt();
digit = new byte[nb];
communicatorInput.readFully(digit);
} catch (IOException e) {
e.printStackTrace();
}
it = listeners.iterator();
while (it.hasNext()){
listener = it.next();
if (digit != null && digit.length > 0) {
message = new String(digit);
// the message was not acknowledged
if(message.contains("NACK")){
try {
listener.onError(message);
if (listener.isDone()) {
listenersToRemove.add(listener);
}
} catch (Exception e){
e.printStackTrace();
}
} else try {
listener.onCompleted(message);
} catch (InvalidObjectException e){
Main.logger.debug(String.format("Response could not be parsed as %s", listener.getCommandType()));
} catch (Exception e){
e.printStackTrace();
}
if (listener.isDone()) {
listenersToRemove.add(listener);
}
}
}
listeners.removeAll(listenersToRemove);
}
}, "receiverThread");
receiverThread.setDaemon(true);
receiverThread.start();
CLIコマンド(それがここには入力を想定していません):
@CliCommand(value="start", help = "Starts stuff")
public void start() throws IOException, InterruptedException {
// this method is passed to the thread with the listener
getAvailabilities().updateAvailabilities("all", "all", "all", someListener);
}
そして、そのリスナーのためのコールバック:
someListener = new CommandListener() {
private String source = "Start some listener";
@Override
public void onCompleted(String r) throws IOException {
System.out.println("Which would you like to start?");
getAvailabilities().printAvailableBrands();
String brandNumber = "";
while(Objects.equals(brandNumber, "")){
System.out.println("Please enter the number of the Brand: ");
//when the callback arrives here I still only see ">spring:" and I get nothing printed on the console
brandNumber = cr.readLine();
if(!isInputAllowed(brandNumber, getAvailabilities().AvailableBrands.size())){
brandNumber = "";
}
}
BrandName = getAvailabilities().AvailableBrands.get(Integer.parseInt(brandNumber) - 1);
//updating the availabilities narrows down the things I list to the console, so I send an update after every selection
getAvailabilities().updateAvailabilities("all", BrandName, "all", getInterfaceListener);
done = true;
}
これはわずかかもしれませんIdeaでCLIをデバッグしているときに、時には奇妙な入力を得るという問題につながります。 start
を挿入するとNo such command as ar
と表示され、もう一度Enterキーを押すと残りの部分が表示されます(No such command as stt
)。