J'ai construit une application Spring CLI qui communique avec un serveur de manière asynchrone. Le serveur a été donné, je ne l'ai pas créé, fondamentalement mon application est requise pour ouvrir un socket TCP et y envoyer un JSON, puis il renvoie un JSON. Il est obligatoire de ne pas utiliser les paramètres CLI, mais dans le rappel de la requête, je souhaite montrer à l'utilisateur un ensemble d'options qu'il doit sélectionner en insérant le numéro correspondant sur la CLI. Très probablement je ne fais pas juste quelque chose, parce qu'après avoir entré la commande, je vois spring>
sur la console (c'est un comportement attendu) et il bloquera le rappel asynchrone à moins que j'appuie sur quelque chose (rien n'est imprimé à la CLI quand je reçois le rappel à moins que j'appuie sur un tas d'entrées - c'est inattendu). Pour lire depuis la console jusqu'ici j'ai utilisé la ligne de commande de JLine, ce que je voudrais réaliser est que quand j'obtiens la réponse du serveur et que le rappel est servi, la console est donnée au thread sur lequel le callback est exécuté (I imprime instantanément le contenu du rappel à la console, et je suis capable de lire l'entrée sans trucs).Async IO gérer dans Spring CLI avec Java comment?
Certains code:
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();
Ensuite, une commande CLI (il attend pas entrée ici):
@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);
}
Et le rappel de cet écouteur:
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;
}
Cela pourrait légèrement se connecter au problème qui parfois lors du débogage de l'interface de ligne de commande dans Idea, il obtient des entrées whacky, par exemple. quand j'insère start
il est dit No such command as ar
, et si j'appuie à nouveau sur entrée, ça va dire (une partie de) le reste: No such command as stt
.