已迁移的bot状态提供程序,但仍调用state.botframework.com

Gre*_*reg 5 c# botframework

我迁移到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

其他潜在的相关信息:

  • 在切换到表azure存储之前,应用程序使用Microsoft State提供程序进行了一段时间的直播
  • 我不会在机器人状态中保留任何关键任务信息,只保留与用户对话的状态; 如果没有重大影响,我可以放松
  • 机器人使用保存在自定义SQL数据库中的恢复cookie发送通知.
  • 这就是Table Azure Provider在Autofac模块中的注册方式:
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)

D4R*_*IDE 3

您的第二个代码片段是来自 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)