2017-12-22 6 views
4

Microsoft 봇 프레임 워크 상태를 관리하기 위해 Table Azure Provider로 마이그레이션했습니다.봇 주 제공자가 이전되었지만 state.botframework.com에 대한 호출이 아직 수행 중입니다

필자의 원격 측정 결과, 새 테이블 Azure 저장소에 대한 의존성 호출이 있지만 state.botframework.com에 대한 호출이 많이 발생하는 것으로 나타 났으며 일부는 보통 느린 응답 시간을 보였습니다.

내가 가진 것처럼이 정상하지 않는 것 기대하는 모든 내 새로운 개인 상태 제공자에게 직접 호출 :

예 : https://xxxxxxxxxx.table.core.windows.net:443/botdata(PartitionKey= '새로운 개인 상태 공급자에 대한 호출의 https://state.botframework.com/v3/botstate/facebook/users/999999999999

예 페이스 북 : 개인 ', RowKey ='xxxxxxxxxxxxxxx입니다-XXXXXXXXXXXXXXXXXXXX

다른 잠재적 인 관련 정보 :

  • 응용 프로그램이 테이블 영원한 저장소로 전환하기 전에 Microsoft State Provider를 사용하여 잠시 동안 살았습니다.
  • 나는 봇 상태의 중요한 정보를 사용자와의 대화 상태 만 유지하지 않습니다. 중요한 영향을 미치지 않고 느슨하게 할 수 있습니다.
  • 봇은 사용자 지정 SQL 데이터베이스에 저장된 다시 시작 쿠키를 사용하여 알림을 보냅니다.
  • 이 표 푸른 제공자가 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(); 
    } 
    
    I 실행중인 서비스 버전에 비해 저장된 상태의 버전을 확인 다음과 같은 방법이있다. 이 코드는 사용자가 새로운 릴리스의 대화 상자에서 변경 한 내용과 호환되지 않는 일련 화 된 대화 상자 상태를 갖기 때문에 도입되었습니다.
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); 
    } 
} 

답변

3

는 두 번째 코드 조각은 그게 Dialog 또는 MessagesController A로부터? 문제가 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()); 
       } 
      } 

의 상태를 조작하는 경우 다음에 실제로

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.")); 
      } 
+1

예를 컨트롤러 합니까? botDataStore.FlushAsync (key, CancellationToken.None); 대화 상태를 포함한 모든 데이터를 제거합니까? – Greg

+0

아니, 실제로 아무것도하지 않으며 사용하지 않아도됩니다. 이전 구현에서 내 스 니펫에 남은 것입니다. – JasonSowers

+1

확인이 버전 변경되면 bady serialize 된 대화 상태가있는 경우 대화 상태를 삭제해야합니다. 어떻게하면 좋을까요? – Greg