MS Bot Framework (Nodejs):会话生命周期和延迟消息
MS Bot Framework (Nodejs): Session lifetime and delayed messages
这是我第一次尝试使用 Bot Framework (Nodejs)。我想测试延迟消息,例如,我的机器人必须在收到消息后 5 秒后回答。
所以我尝试了这段代码:
var builder = require('botbuilder');
var connector = new builder.consoleconnector().listen();
var bot = new builder.universalbot(connector);
bot.dialog('/', function (session) {
if (!session.userData.TimeoutStarted) {
session.send("I'll answer in 5 seconds");
session.userData.TimeoutStarted = true;
setTimeout(function() {
session.send("Answer after 5 seconds");
session.userData.TimeoutStarted = false;
}, 5000);
} else {
session.send("Bot is busy");
}
});
但这行不通。 setTimeout 中的回调函数触发,但所有与会话的操作根本不起作用。
所以,我在这里找到了可能的解决方案: 并重写了我的代码:
var builder = require('botbuilder');
var connector = new builder.ConsoleConnector().listen();
var bot = new builder.UniversalBot(connector);
bot.dialog('/', function (session) {
if (session.userData.Timeout > 0 && Date.now() - session.userData.Timeout > 5000)
session.userData.Timeout = 0;
if (!session.userData.Timeout) {
session.send("I'll answer in 5 seconds");
var reply = session.message;
setTimeout(function() {
reply.text = "Answer after 5 seconds";
bot.send(reply);
}, 5000);
session.userData.Timeout = Date.now();
} else {
session.send("Bot is busy");
}
});
此代码有效,但经过这么多检查后看起来很糟糕。所以我有几个问题:
- 为什么第一个代码示例不起作用?我猜是会话生命周期中的问题然后什么是会话生命周期?
- 本例中如何设置session.userData?所以在第一个代码示例中,我想在 setTimeout 的回调函数中设置它,但它也不起作用。
- 创建延迟答案的最佳方法是什么?
我刚刚调查了这个问题。 ConsoleConnector
中似乎存在一个错误,导致无法使用相同的 session
对象发送两条消息(由于内部批处理,消息之间的给定间隔以上)。由于状态也在 send
期间持续存在,您的延迟状态更新也将不起作用。如果您将对 session.save
的调用添加到 setTimeout
中的回调,它将保持新状态(但仍不会发送消息)。
我相信您的第一个示例应该与 ChatConnector
一起使用(尽管还没有机会尝试)。我将创建一个包含 ConsoleConnector
.
修复的拉取请求
我希望这能回答你所有的问题。
更新
有关更多详细信息,请参阅 this issue 和相关的拉取请求。
更新2
它适用于 ChatConnector
,使用此代码:
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
var connector = new builder.ChatConnector({
appId: '',
appPassword: ''
});
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());
bot.dialog('/', function (session) {
if (!session.userData.TimeoutStarted) {
session.send("I'll answer in 5 seconds");
session.userData.TimeoutStarted = true;
setTimeout(function() {
session.send("Answer after 5 seconds");
session.userData.TimeoutStarted = false;
}, 5000);
} else {
session.send("Bot is busy");
}
});
对于有兴趣从机器人发送延迟消息的人,您可以使用 session.delay(<ms>)
例如,
session.send('msg')
session.delay(5000) // delay 5 seconds
session.endDialog()
这是我第一次尝试使用 Bot Framework (Nodejs)。我想测试延迟消息,例如,我的机器人必须在收到消息后 5 秒后回答。 所以我尝试了这段代码:
var builder = require('botbuilder');
var connector = new builder.consoleconnector().listen();
var bot = new builder.universalbot(connector);
bot.dialog('/', function (session) {
if (!session.userData.TimeoutStarted) {
session.send("I'll answer in 5 seconds");
session.userData.TimeoutStarted = true;
setTimeout(function() {
session.send("Answer after 5 seconds");
session.userData.TimeoutStarted = false;
}, 5000);
} else {
session.send("Bot is busy");
}
});
但这行不通。 setTimeout 中的回调函数触发,但所有与会话的操作根本不起作用。
所以,我在这里找到了可能的解决方案:
var builder = require('botbuilder');
var connector = new builder.ConsoleConnector().listen();
var bot = new builder.UniversalBot(connector);
bot.dialog('/', function (session) {
if (session.userData.Timeout > 0 && Date.now() - session.userData.Timeout > 5000)
session.userData.Timeout = 0;
if (!session.userData.Timeout) {
session.send("I'll answer in 5 seconds");
var reply = session.message;
setTimeout(function() {
reply.text = "Answer after 5 seconds";
bot.send(reply);
}, 5000);
session.userData.Timeout = Date.now();
} else {
session.send("Bot is busy");
}
});
此代码有效,但经过这么多检查后看起来很糟糕。所以我有几个问题:
- 为什么第一个代码示例不起作用?我猜是会话生命周期中的问题然后什么是会话生命周期?
- 本例中如何设置session.userData?所以在第一个代码示例中,我想在 setTimeout 的回调函数中设置它,但它也不起作用。
- 创建延迟答案的最佳方法是什么?
我刚刚调查了这个问题。 ConsoleConnector
中似乎存在一个错误,导致无法使用相同的 session
对象发送两条消息(由于内部批处理,消息之间的给定间隔以上)。由于状态也在 send
期间持续存在,您的延迟状态更新也将不起作用。如果您将对 session.save
的调用添加到 setTimeout
中的回调,它将保持新状态(但仍不会发送消息)。
我相信您的第一个示例应该与 ChatConnector
一起使用(尽管还没有机会尝试)。我将创建一个包含 ConsoleConnector
.
我希望这能回答你所有的问题。
更新
有关更多详细信息,请参阅 this issue 和相关的拉取请求。
更新2
它适用于 ChatConnector
,使用此代码:
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
var connector = new builder.ChatConnector({
appId: '',
appPassword: ''
});
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());
bot.dialog('/', function (session) {
if (!session.userData.TimeoutStarted) {
session.send("I'll answer in 5 seconds");
session.userData.TimeoutStarted = true;
setTimeout(function() {
session.send("Answer after 5 seconds");
session.userData.TimeoutStarted = false;
}, 5000);
} else {
session.send("Bot is busy");
}
});
对于有兴趣从机器人发送延迟消息的人,您可以使用 session.delay(<ms>)
例如,
session.send('msg')
session.delay(5000) // delay 5 seconds
session.endDialog()