java - 我的消息在 BotFramework - Java 中未按正确的顺序发送

标签 java botframework synchronized

我的主 Controller 中有两个主要方法,它们是:

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 ,“你好”); sendMessage( Activity ,“世界!”); sendQuestion(activity, PostQuestion.askHello())

有时我的顺序是“消息 - 问题(消息) - 消息”,而不是“消息 - 消息 - 问题”。

我的问题与线程有关吗? (我不在我的应用程序中执行多线程)。 我尝试对我的两种方法使用同步关键字,但我的问题仍然存在。

感谢您的帮助!

最佳答案

由于机器人是一个网络应用程序,并且您将处理 REST API 调用等,因此实际上没有办法不异步。例如,每次使用 sendToConversation 从机器人向用户发送消息时,这就是一个异步操作。 Bot Builder Java SDK 使用可完成的 future 来处理异步,您也应该这样做。看看Welcome User sample了解如何使用可完成的 future 来确保异步操作一个接一个地执行,并等待每个操作依次完成:

/**
 * 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 仍处于预览阶段,因此即使您所做的一切正确,您也将面临遇到问题的风险。

关于java - 我的消息在 BotFramework - Java 中未按正确的顺序发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58648368/

相关文章:

java - Netbeans 平台和菜单

Java 保证死锁

java - swingWorker调用的synchronized方法被中断?

java - 使用 Java YouTubeService 类进行经过身份验证的 YouTube API 调用时,关键字对象为空

java - 如何连接 Hibernate 和 Drools

javascript - MS Bot Framework 将值从服务器代码 (C#) 传递到前端代码 (JavaScript)

bots - Microsoft bot 框架获取用户时区

java - 使用 System.out.println(Thread.currentThread().getName() + ""+count);导致同步

java - Java中的正则表达式删除所有带有尾随空格的 '\r\n',除了文件末尾的任何空格

node.js - 自适应卡 : how to use in Node. js