Managing state (Status beheren)
VAN TOEPASSING OP: SDK v4
De status in een bot volgt dezelfde paradigma's als moderne webtoepassingen en de Bot Framework SDK biedt een aantal abstracties om statusbeheer gemakkelijker te maken.
Net als bij webtoepassingen is een bot inherent staatloos. Elke willekeurige wending in het gesprek kan worden afgehandeld door een andere instantie van uw bot. Voor sommige bots heeft deze eenvoud de voorkeur: de bot kan werken zonder aanvullende informatie of de vereiste informatie staat gegarandeerd in het binnenkomende bericht. Voor anderen is de status (zoals waar het gesprek is gebleven of eerder ontvangen gegevens over de gebruiker) nodig om een nuttig gesprek te kunnen voeren.
Waarom heb ik een status nodig?
Door de status te behouden, kan uw bot zinvollere gesprekken voeren door bepaalde dingen over een gebruiker of gesprek te onthouden. Als u bijvoorbeeld eerder met een gebruiker hebt gesproken, kunt u eerdere informatie over deze gebruiker opslaan, zodat u er niet opnieuw om hoeft te vragen. Status bewaart gegevens ook langer dan de huidige beurt, zodat uw bot informatie bewaart tijdens een gesprek met meerdere paden.
Omdat het betrekking heeft op bots, zijn er een paar lagen voor het gebruik van status: de opslaglaag, statusbeheer (opgenomen in de botstatus in het onderstaande diagram) en toegangsbeheer voor statuseigenschappen. Dit diagram illustreert delen van de interactiereeks tussen deze lagen, met de ononderbroken pijlen die een methode-aanroep vertegenwoordigen en de stippelpijlen die het antwoord vertegenwoordigen (met of zonder retourwaarde).
De stroom van dit diagram wordt uitgelegd in de volgende secties met details over elk van deze lagen.
Opslaglaag
Vanaf de back-end, waar de statusgegevens daadwerkelijk worden opgeslagen, is de opslaglaag. Dit kan worden beschouwd als uw fysieke opslag, zoals in het geheugen, Azure of een server van derden.
De Bot Framework SDK bevat enkele implementaties voor de opslaglaag:
- Geheugenopslag implementeert opslag in het geheugen voor testdoeleinden. Gegevensopslag in het geheugen is alleen bedoeld voor lokale tests omdat deze opslag vluchtig en tijdelijk is. De gegevens worden gewist telkens wanneer de bot opnieuw wordt opgestart.
- Azure Blob Storage maakt verbinding met een Azure Blob Storage objectdatabase.
- Gepartitioneerde Azure Cosmos DB-opslag maakt verbinding met een gepartitioneerde Cosmos DB NoSQL-database.
Belangrijk
De Cosmos DB-opslagklasse is afgeschaft. Containers die oorspronkelijk waren gemaakt met CosmosDbStorage hadden geen partitiesleutel ingesteld en kregen de standaardpartitiesleutel '/_partitionKey'.
Containers die zijn gemaakt met Cosmos DB-opslag , kunnen worden gebruikt met gepartitioneerde Cosmos DB-opslag. Lees Partitionering in Azure Cosmos DB voor meer informatie.
Houd er ook rekening mee dat, in tegenstelling tot de verouderde Cosmos DB-opslag, de gepartitioneerde Cosmos DB-opslag niet automatisch een database binnen uw Cosmos DB-account maakt. U moet handmatig een nieuwe database maken, maar het handmatig maken van een container overslaan, omdat CosmosDbPartitionedStorage de container voor u maakt.
Zie Rechtstreeks naar opslag schrijven voor instructies over het maken van verbinding met andere opslagopties.
Statusbeheer
Statusbeheer automatiseert het lezen en schrijven van de status van uw bot naar de onderliggende opslaglaag. Status wordt opgeslagen als statuseigenschappen. Dit zijn in feite sleutel-waardeparen die uw bot kan lezen en schrijven via het statusbeheerobject zonder dat u zich zorgen hoeft te maken over de specifieke onderliggende implementatie. Deze statuseigenschappen bepalen hoe die informatie wordt opgeslagen. Wanneer u bijvoorbeeld een eigenschap ophaalt die u hebt gedefinieerd als een specifieke klasse of een specifiek object, weet u hoe die gegevens worden gestructureerd.
Deze statuseigenschappen worden samengevoegd in scoped 'buckets', wat slechts verzamelingen zijn om deze eigenschappen te ordenen. De SDK bevat drie van deze 'buckets':
- Gebruikersstatus
- Gespreksstatus
- Status van privégesprek
Al deze buckets zijn subklassen van de statusklasse van de bot, die kunnen worden afgeleid om andere typen buckets met verschillende bereiken te definiëren.
Deze vooraf gedefinieerde buckets hebben een bepaalde zichtbaarheid, afhankelijk van de bucket:
- De gebruikersstatus is beschikbaar op elke beurt dat de bot met die gebruiker in dat kanaal aan het praten is, ongeacht het gesprek
- De gespreksstatus is beschikbaar in een specifiek gesprek, ongeacht de gebruiker, zoals in groepsgesprekken
- De status van het privégesprek is gericht op zowel het specifieke gesprek als die specifieke gebruiker
Tip
Zowel de gebruikers- als de gespreksstatus worden per kanaal bepaald. Dezelfde persoon die verschillende kanalen gebruikt om toegang te krijgen tot uw bot, wordt weergegeven als verschillende gebruikers, één voor elk kanaal en elk met een afzonderlijke gebruikersstatus.
De sleutels die voor elk van deze vooraf gedefinieerde buckets worden gebruikt, zijn specifiek voor de gebruiker en het gesprek, of beide. Bij het instellen van de waarde van uw statuseigenschap wordt de sleutel intern voor u gedefinieerd, met informatie op de turncontext om ervoor te zorgen dat elke gebruiker of gesprek in de juiste bucket en eigenschap wordt geplaatst. De sleutels worden met name als volgt gedefinieerd:
- De gebruikersstatus maakt een sleutel met behulp van de kanaal-id en van id. Bijvoorbeeld {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName
- De gespreksstatus maakt een sleutel met behulp van de kanaal-id en de gespreks-id. Bijvoorbeeld {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName
- De status van het privégesprek maakt een sleutel met behulp van de kanaal-id, van id en gespreks-id. Bijvoorbeeld {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName
Wanneer moet u elk type status gebruiken
De gespreksstatus is geschikt voor het bijhouden van de context van het gesprek, zoals:
- Of de bot de gebruiker een vraag heeft gesteld en welke vraag dat was
- Wat het huidige gespreksonderwerp is of wat het laatste gespreksonderwerp was
Gebruikersstatus is geschikt voor het bijhouden van informatie over de gebruiker, zoals:
- Niet-kritieke gebruikersgegevens, zoals naam en voorkeuren, een alarminstelling of een waarschuwingsvoorkeur
- Informatie over het laatste gesprek met de bot
- Een bot voor productondersteuning kan bijvoorbeeld bijhouden naar welke producten de gebruiker heeft gevraagd.
De status van een privégesprek is geschikt voor kanalen die ondersteuning bieden voor groepsgesprekken, maar waar u zowel gebruikers- als gespreksspecifieke informatie wilt bijhouden. Als u bijvoorbeeld een klas-clicker-bot hebt:
- De bot kan antwoorden van leerlingen/studenten voor een bepaalde vraag aggregeren en weergeven.
- De bot kan de prestaties van elke leerling/student aggregeren en deze aan het einde van de sessie privé aan hen doorgeven.
Zie het artikel met instructies over de status voor meer informatie over het gebruik van deze vooraf gedefinieerde buckets.
Verbinding maken met meerdere databases
Als uw bot verbinding moet maken met meerdere databases, maakt u een opslaglaag voor elke database. U kunt ervoor kiezen om meerdere databases te gebruiken als uw bot gegevens verzamelt met verschillende behoeften op het gebied van beveiliging, gelijktijdigheid of gegevenslocatie.
Maak voor elke opslaglaag de statusbeheerobjecten die u nodig hebt om uw statuseigenschappen te ondersteunen.
Toegangsbeheer voor statuseigenschap
Accessors voor statuseigenschappen worden gebruikt om een van uw statuseigenschappen daadwerkelijk te lezen of te schrijven en bieden methoden voor ophalen, instellen en verwijderen voor toegang tot uw statuseigenschappen vanuit een beurt. Als u een accessor wilt maken, moet u de naam van de eigenschap opgeven. Deze vindt meestal plaats wanneer u uw bot initialiseert. Vervolgens kunt u die accessor gebruiken om die eigenschap van de status van uw bot op te halen en te bewerken.
Met de accessors kan de SDK de status van de onderliggende opslag ophalen en de statuscache van de bot voor u bijwerken. De statuscache is een lokale cache die wordt onderhouden door uw bot die het statusobject voor u opslaat, zodat lees- en schrijfbewerkingen mogelijk zijn zonder toegang tot de onderliggende opslag. Als deze zich nog niet in de cache bevindt, wordt met het aanroepen van de get-methode van de accessor de status opgehaald en ook in de cache geplaatst. Zodra de statuseigenschap is opgehaald, kan deze worden gemanipuleerd, net als bij een lokale variabele.
Met de verwijderingsmethode van de accessor wordt de eigenschap uit de cache verwijderd en ook uit de onderliggende opslag verwijderd.
Belangrijk
Voor de eerste aanroep van de get-methode van een accessor moet u een factory-methode opgeven om het object te maken als het nog niet bestaat in uw status. Als er geen factory-methode wordt opgegeven, krijgt u een uitzondering. Meer informatie over het gebruik van een factory-methode vindt u in het artikel state-how-to.
Als u wijzigingen wilt behouden die u aanbrengt in de statuseigenschap die u van de accessor krijgt, moet de eigenschap in de statuscache worden bijgewerkt. U kunt dit doen via een aanroep van de toegangssetmethode , waarmee de waarde van uw eigenschap in de cache wordt ingesteld en beschikbaar is als dat later op die beurt moet worden gelezen of bijgewerkt. Als u die gegevens daadwerkelijk wilt behouden in de onderliggende opslag (en dus beschikbaar wilt maken na de huidige turn), moet u uw status opslaan.
Hoe de toegangsmethoden voor de statuseigenschap werken
De toegangsmethoden zijn de primaire manier voor uw bot om te communiceren met de status. De werking en de interactie tussen de onderliggende lagen zijn als volgt:
- De get-methode van de accessor:
- De eigenschap Accessor vraagt de eigenschap aan van de statuscache.
- Als de eigenschap zich in de cache bevindt, retourneert u deze. Anders haalt u deze op uit het statusbeheerobject. (Als deze nog niet in de status is, gebruikt u de factory-methode die is opgegeven in de aanroep van de accessors.)
- De setmethode van de accessor:
- Werk de statuscache bij met de nieuwe eigenschapswaarde.
- De opslagmethode van het statusbeheerobject:
- Controleer de wijzigingen in de eigenschap in de statuscache.
- Schrijf die eigenschap naar de opslag.
Status in dialoogvensters
De dialoogvensterbibliotheek maakt gebruik van een accessor voor de eigenschappen van de dialoogvensterstatus, gedefinieerd in de gespreksstatus van de bot, om de plaats van een dialoogvenster in het gesprek te behouden. Met de eigenschap Dialoogvensterstatus kan elk dialoogvenster ook tijdelijke informatie opslaan tussen de beurten.
Adaptieve dialoogvensters hebben een uitgebreidere geheugenbereikstructuur, waardoor het eenvoudiger is om onder andere toegang te krijgen tot configuratie- en herkenningsresultaten. Het dialoogvensterbeheer maakt gebruik van de beheerobjecten voor gebruikers- en gespreksstatus om deze geheugenbereiken te bieden.
Zie het artikel over de dialoogvensterbibliotheek voor meer informatie over de dialoogvensterbibliotheek .
- Zie over onderdeel- en watervaldialoogvensters voor informatie die specifiek is voor deze typen dialoogvensters.
- Zie de inleiding tot adaptieve dialoogvensters en het beheren van de status in artikelen over adaptieve dialoogvensters voor informatie die specifiek is voor adaptieve dialoogvensters.
Status opslaan
Wanneer u de ingestelde methode van de accessor aanroept om de bijgewerkte status vast te leggen, is die statuseigenschap nog niet opgeslagen in uw permanente opslag en wordt deze in plaats daarvan alleen opgeslagen in de statuscache van uw bot. Als u wijzigingen in de statuscache wilt opslaan in uw permanente status, moet u de opslagmethode van het statusbeheerobject aanroepen, die beschikbaar is voor de implementatie van de hierboven genoemde botstatusklasse (zoals gebruikersstatus of gespreksstatus).
Als u de methode voor het opslaan van wijzigingen voor een statusbeheerobject (zoals de hierboven genoemde buckets) aanroept, worden alle eigenschappen in de statuscache opgeslagen die u tot dat moment hebt ingesteld voor die bucket, maar niet voor een van de andere buckets die mogelijk de status van uw bot hebben.
Tip
Botstatus implementeert een 'last write wins'-gedrag, waarbij de laatste schrijfbewerking de eerder geschreven status overschrijft. Dit kan voor veel toepassingen werken, maar heeft gevolgen, met name in uitgeschaalde scenario's, waarbij er sprake kan zijn van een zekere mate van gelijktijdigheid of latentie.
Als u een aantal aangepaste middleware hebt die de status mogelijk bijwerkt nadat de beurthandler is voltooid, kunt u de status in middleware afhandelen.