我的消息在 BotFramework 中的发送顺序不正确 - Java
My messages aren't sent in the right order in BotFramework - Java
我的主控制器中有两个主要方法,它们是:
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())
有时我有以下顺序 "Message - Question (message) - Message" 而不是 "Message - Message - Question"。
我的问题是关于线程的吗? (我不在我的应用程序中进行多线程处理)。
我尝试为我的两种方法使用 synchronized 关键字,但我的问题仍然存在。
感谢您的帮助!
由于机器人是一个 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 仍处于预览阶段,因此即使您做对了所有事情,您也有 运行 遇到问题的风险。
我的主控制器中有两个主要方法,它们是:
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())
有时我有以下顺序 "Message - Question (message) - Message" 而不是 "Message - Message - Question"。
我的问题是关于线程的吗? (我不在我的应用程序中进行多线程处理)。 我尝试为我的两种方法使用 synchronized 关键字,但我的问题仍然存在。
感谢您的帮助!
由于机器人是一个 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 仍处于预览阶段,因此即使您做对了所有事情,您也有 运行 遇到问题的风险。