我已經構建了一個以異步方式與服務器通信的Spring CLI應用程序。服務器是給定的,我沒有創建它,基本上我的應用程序需要打開一個TCP套接字並通過它發送JSON,然後它發回一個JSON。強制不使用CLI參數,而是在請求的回調中,我想通過在CLI上插入相應的編號來向用戶顯示一組需要選擇的選項。很可能我沒有做正確的事情,因爲在輸入命令後,我在控制檯上看到spring>
(這是一個預期的行爲),並且它將阻止異步回調,除非我按下某些內容(當我收到時沒有任何內容被打印到CLI除非我按下一堆輸入 - 這是意想不到的)。爲了從控制檯讀取到目前爲止我使用的JLine的命令行,我想實現的是當我從服務器獲得響應並且回調被提供時,控制檯被賦予正在運行回調的線程(I即時將回調的內容打印到控制檯,並且我可以在沒有任何技巧的情況下讀取輸入內容)。在Spring CLI中使用Java進行異步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
,如果我再次按下輸入,它會說(其中一些)其餘的:No such command as stt
。