BotFramework中的消息发送顺序不正确-Java

时间:2019-10-31 17:17:28

标签: java botframework synchronized

我的主控制器中有两个主要方法:

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关键字,但问题仍然存在。

感谢您的帮助!

1 个答案:

答案 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仍处于预览状态,因此即使您做对了所有事情,也有可能遇到问题。