我的主控制器中有两个主要方法:
public synchronized void sendQuestion(Activity activity, PostQuestion pq) {
Map<String, Object> map = allConversations.get(activity.getConversation().getId());
map.put("command", pq.getQuestionId()); //It will run a command at next user input
allConversations.put(activity.getConversation().getId(), map); //Store all conversation data
sendMessage(activity, pq.getQuestionLabel()); //QuestionLabel is a string
}
public boolean sendMessage(Activity activity, String msg) {
Activity reply = activity.createReply(msg);
try {
this.connector.getConversations()
.sendToConversation(
activity.getConversation().getId(),
reply);
return true;
} catch (Exception e) {
return false;
}
}
我的机器人是基本的QnA机器人。它从API检索数据,然后发送结果。答案后问问题。 我的问题是: 例如,如果我使用sendMessage方法发送两条消息,然后使用sendQuestion(也发送消息)发送一条消息:
sendMessage(activity, "Hello");
sendMessage(activity, "World!");
sendQuestion(activity, PostQuestion.askHello())
有时候我会按照以下顺序“消息-问题(消息)-消息”而不是“消息-消息-问题”。
我是关于线程的问题吗? (我不在应用程序中执行多线程处理)。 我为这两种方法尝试了synced关键字,但问题仍然存在。
感谢您的帮助!
答案 0 :(得分:2)
由于机器人是Web应用程序,并且您将要处理REST API调用等,所以实际上没有办法保持异步。例如,每次您使用sendToConversation
从bot向用户发送消息时,这都是异步操作。 Bot Builder Java SDK使用可替代的期货来处理异步,您也应该这样做。看看Welcome User sample,了解如何使用可完成的期货来确保异步操作一个接一个地执行,依次等待每个操作完成:
/**
* This will prompt for a user name, after which it will send info about the conversation. After sending
* information, the cycle restarts.
*
* @param turnContext The context object for this turn.
* @return A future task.
*/
@Override
protected CompletableFuture<Void> onMessageActivity(TurnContext turnContext) {
// Get state data from UserState.
StatePropertyAccessor<WelcomeUserState> stateAccessor = userState.createProperty("WelcomeUserState");
CompletableFuture<WelcomeUserState> stateFuture = stateAccessor.get(turnContext, WelcomeUserState::new);
return stateFuture.thenApply(thisUserState -> {
if (!thisUserState.getDidBotWelcomeUser()) {
thisUserState.setDidBotWelcomeUser(true);
String userName = turnContext.getActivity().getFrom().getName();
return turnContext.sendActivities(
MessageFactory.text(FIRST_WELCOME_ONE),
MessageFactory.text(String.format(FIRST_WELCOME_TWO, userName))
);
} else {
String text = turnContext.getActivity().getText().toLowerCase();
switch (text) {
case "hello":
case "hi":
return turnContext.sendActivities(MessageFactory.text("You said " + text));
case "intro":
case "help":
return sendIntroCard(turnContext);
default:
return turnContext.sendActivity(WELCOMEMESSAGE);
}
}
})
// make the return value happy.
.thenApply(resourceResponse -> null);
}
还请记住,Java SDK仍处于预览状态,因此即使您做对了所有事情,也有可能遇到问题。