我迁移到Table Azure Provider以管理Microsoft bot框架状态.
在我的遥测中,我看到依赖关系调用我的新表Azure存储,但是我仍然看到很多调用state.botframework.com,有些调用通常是随机的慢响应时间.
这似乎不正常,因为我希望所有的调用都被定向到我的新私有状态提供者:
示例:https: //state.botframework.com/v3/botstate/facebook/users/999999999999
:调用新的私有状态提供的示例 https://xxxxxxxxxx.table.core.windows.net:443/botdata(PartitionKey=的Facebook:私人",RowKey ='XXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXX
其他潜在的相关信息:
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
//Register custom datastore
builder
.RegisterKeyedType<TableBotDataStore, IBotDataStore<BotData>>()
.Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
.WithParameter((pi, c) => pi.Name == "connectionString",
(pi, c) =>
ConfigurationManager.ConnectionStrings["X"].ConnectionString)
.SingleInstance();
builder.RegisterAdapterChain<IBotDataStore<BotData>>
(
typeof(TableBotDataStore),
typeof(CachingBotDataStore)
)
.InstancePerLifetimeScope();
}
Run Code Online (Sandbox Code Playgroud)
public static async Task CheckClientVersion(Activity activity)
{
StateClient stateClient = activity.GetStateClient();
BotData userData = stateClient.BotState.GetUserData(activity.ChannelId, activity.From.Id);
if (userData?.GetProperty<string>("version")?.CompareTo(Assembly.GetExecutingAssembly().GetName().Version.ToString()) != 0)
{
string[] result = await stateClient.BotState.DeleteStateForUserAsync(activity.ChannelId, activity.From.Id, CancellationToken.None);
userData = stateClient.BotState.GetUserData(activity.ChannelId, activity.From.Id);
userData.SetProperty<string>("version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
await stateClient.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);
}
}
Run Code Online (Sandbox Code Playgroud)
您的第二个代码片段是来自 aDialog或 吗MessagesController?问题是您正在使用activity.GetStateClient它始终调用默认状态客户端而不是您自己的自定义客户端。
为了实现您想要的目标,如果您正在操纵状态,则必须使用类似于下面的代码MessagesController
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
var message = activity as IMessageActivity;
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
var key = Address.FromActivity(message);
var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);
userData.SetProperty("key 1", "value1");
userData.SetProperty("key 2", "value2");
await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
await botDataStore.FlushAsync(key, CancellationToken.None);
}
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
}
}
Run Code Online (Sandbox Code Playgroud)
回答您的后续问题:
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
var token = new CancellationToken();
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(token);
var stack = scope.Resolve<IDialogStack>();
stack.Reset();
botData.UserData.Clear();
botData.ConversationData.Clear();
botData.PrivateConversationData.Clear();
await botData.FlushAsync(token);
var botToUser = scope.Resolve<IBotToUser>();
await botToUser.PostAsync(message.CreateReply($"{timerMessage} Conversation aborted."));
}
Run Code Online (Sandbox Code Playgroud)