Как сделать задержку между двумя сообщениями в рамках бота - Node.js - PullRequest
2 голосов
/ 04 октября 2019

Я занимаюсь разработкой бота, который подключен к нашему клиентскому приложению с помощью Direct Line с использованием Botbuilder JS V4. по некоторым причинам сообщения отправляются с неправильным порядком боту. Например:

  • Пользователь: привет

  • Бот: Чем я могу вам помочь?

  • Бот: ПриветЯ робот.

В качестве решения я добавил задержку в две секунды между сообщениями во многих диалогах моего бота.

Как правильно это сделать? И это рекомендуемый способ решения этой проблемы?

Использование setTimeout ()

async greetUser(step) {
  ...
  await step.context.sendActivity(firstReply);
  setTimeout(() => {
    await step.context.sendActivity(secondReply);
  }, 2000);
}

Использование sleep ()

const sleep = require("util").promisify(setTimeout);

async greetUser(step) {
  ...
  await step.context.sendActivity(firstReply);
  await sleep(2000);
  await step.context.sendActivity(secondReply);
}

После добавления многих функций sleep () я заметил, что это влияет на производительность бота. Бот не отвечал в производственной среде. и выдает эту ошибку:

[onTurnErrorStack]: Error
   at new RestError (D:\home\site\wwwroot\node_modules\@azure\ms-rest-js\dist\msRest.node.js:1397:28)
   at D:\home\site\wwwroot\node_modules\@azure\ms-rest-js\dist\msRest.node.js:1849:37
   at <anonymous>
   at process._tickDomainCallback (internal/process/next_tick.js:228:7)
[onTurnError]: {"statusCode":401,"request":{"streamResponseBody":false,"url":"https://directline.botframework.com/v3/conversations/DxjYZQsdv16sdULAsaIn8iQ-h/activities/DxjYZQ65dffgsaIn8iQ-h%7C0000000","method":"POST","headers":{"_

Есть предложения по решению этой проблемы?

Ответы [ 2 ]

4 голосов
/ 05 октября 2019

Если вы используете значение по умолчанию BotFrameworkAdapter, вы также можете использовать delay ActivityType. Это добавит задержку без дополнительного кода ( source ).

Вы также можете попробовать метод sendActivities, согласно документации это также сохранит порядок. Действия будут отправляться одна за другой в порядке их поступления. Ответный объект будет возвращен для каждого отправленного действия. Для операций message это будет содержать идентификатор доставленного сообщения.

async greetUser(step) {
    await step.context.sendActivities([
        { type: 'message', text: 'First reply' },
        { type: 'delay', value: 2000 },
        { type: 'message', text: 'Second reply' }
    ]);
}
3 голосов
/ 04 октября 2019

У меня была похожая проблема, когда я регистрировал записи и ответ перезаписывал запрос. Я нашел простой цикл, который позволил мне установить задержку в мс, и он отлично работал для меня. Функция ожидания:

    async wait(milliseconds) {
        var start = new Date().getTime();
        for (var i = 0; i < 1e7; i++) {
            if ((new Date().getTime() - start) > milliseconds) {
                break;
            }
        }
    }

Так что вы должны иметь возможность вызывать ее следующим образом:

async greetUser(step) {
  ...
  await step.context.sendActivity(firstReply);
  await this.wait(2000);
  await step.context.sendActivity(secondReply);
}

Теперь это похоже на функцию сна, с которой у меня нет опытас участием. У меня не было никаких проблем с ним, и он вызывается дважды за ход, чтобы зарегистрировать и запрос, и ответ, хотя моя задержка составляет всего 250 мс, а не 2000.

Мне было бы интересно узнать, есть лиэто лучший способ ввести задержку разговора.

Редактировать: Как уже упоминалось в комментариях ниже, ожидание обещания было бы лучшим решением. Но оставив здесь оригинальный ответ на случай, если это кому-то выгодно. Внутри асинхронной функции кажется, что await new Promise(resolve => setTimeout(resolve,2000)); даст те же результаты без недостатков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...