Scrivere direttamente nell'archivio
SI APPLICA A: SDK v4
È possibile leggere e scrivere direttamente nell'oggetto di archiviazione senza usare un oggetto middleware o contesto. Questo modo di operare può essere appropriato per i dati che il bot usa per mantenere una conversazione o per i dati che provengono da un'origine esterna al flusso della conversazione del bot. In questo modello di archiviazione dei dati i dati vengono letti direttamente dall'archiviazione invece di usare un gestore di stato. Gli esempi di codice in questo articolo illustrano come leggere e scrivere dati nell'archiviazione usando memoria, Cosmos DB, BLOB di Azure e archiviazione trascrizioni BLOB di Azure.
Nota
Gli SDK JavaScript, C# e Python di Bot Framework continueranno a essere supportati, ma Java SDK verrà ritirato con il supporto finale a lungo termine che termina a novembre 2023.
I bot esistenti creati con Java SDK continueranno a funzionare.
Per la creazione di nuovi bot, è consigliabile usare Microsoft Copilot Studio e leggere le informazioni sulla scelta della soluzione copilota appropriata.
Per altre informazioni, vedere Il futuro della compilazione di bot.
Prerequisiti
- Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.
- Familiarità con la creazione di un bot in locale.
- Modelli di bot Framework SDK v4 per Visual Studio (C#), Node.js o Yeoman.
Nota
È possibile installare i modelli da Visual Studio.
- Nel menu selezionare Estensioni e quindi Gestisci estensioni.
- Nella finestra di dialogo Gestisci estensioni cercare e installare i modelli di Bot Framework v4 SDK per Visual Studio.
Per informazioni sulla distribuzione di bot .NET in Azure, vedere Come effettuare il provisioning e pubblicare un bot.
Informazioni sull'esempio
Il codice di esempio in questo articolo inizia con la struttura di un bot Echo di base, quindi estende la funzionalità di tale bot aggiungendo altro codice (fornito di seguito). Questo codice esteso crea un elenco per mantenere gli input utente man mano che vengono ricevuti. Ogni turno, l'elenco completo degli input utente, salvato in memoria, viene restituito all'utente. La struttura di dati contenente questo elenco di input viene quindi modificata per salvare nell'archiviazione. Vari tipi di archiviazione vengono esaminati man mano che vengono aggiunte funzionalità aggiuntive a questo codice di esempio.
Archiviazione in memoria
Bot Framework SDK permette di archiviare gli input dell'utente tramite l'archiviazione in memoria. Poiché l'archiviazione in memoria viene cancellata ogni volta che il bot viene riavviato, è più adatto per scopi di test e non è destinato all'uso in produzione. I tipi di archiviazione permanente, come l'archiviazione database, sono più adatti per i bot di produzione.
Creare un bot di base
Nella parte restante di questo argomento verrà creato un bot Echo. Il codice di esempio del bot Echo può essere compilato in locale seguendo le istruzioni di avvio rapido per creare un bot.
Sostituire il codice in EchoBot.cs con il codice seguente:
using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
// Represents a bot saves and echoes back user input.
public class EchoBot : ActivityHandler
{
// Create local Memory Storage.
private static readonly MemoryStorage _myStorage = new MemoryStorage();
// Create cancellation token (used by Async Write operation).
public CancellationToken cancellationToken { get; private set; }
// Class for storing a log of utterances (text of messages) as a list.
public class UtteranceLog : IStoreItem
{
// A list of things that users have said to the bot
public List<string> UtteranceList { get; } = new List<string>();
// The number of conversational turns that have occurred
public int TurnNumber { get; set; } = 0;
// Create concurrency control where this is used.
public string ETag { get; set; } = "*";
}
// Echo back user input.
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// preserve user input.
var utterance = turnContext.Activity.Text;
// Make empty local log-items list.
UtteranceLog logItems = null;
// See if there are previous messages saved in storage.
try
{
string[] utteranceList = { "UtteranceLog" };
logItems = _myStorage.ReadAsync<UtteranceLog>(utteranceList).Result?.FirstOrDefault().Value;
}
catch
{
// Inform the user an error occurred.
await turnContext.SendActivityAsync("Sorry, something went wrong reading your stored messages!");
}
// If no stored messages were found, create and store a new entry.
if (logItems is null)
{
// Add the current utterance to a new object.
logItems = new UtteranceLog();
logItems.UtteranceList.Add(utterance);
// Set initial turn counter to 1.
logItems.TurnNumber++;
// Show user new user message.
await turnContext.SendActivityAsync($"{logItems.TurnNumber}: The list is now: {string.Join(", ", logItems.UtteranceList)}");
// Create dictionary object to hold received user messages.
var changes = new Dictionary<string, object>();
{
changes.Add("UtteranceLog", logItems);
}
try
{
// Save the user message to your Storage.
await _myStorage.WriteAsync(changes, cancellationToken);
}
catch
{
// Inform the user an error occurred.
await turnContext.SendActivityAsync("Sorry, something went wrong storing your message!");
}
}
// Else, our storage already contained saved user messages, add new one to the list.
else
{
// add new message to list of messages to display.
logItems.UtteranceList.Add(utterance);
// increment turn counter.
logItems.TurnNumber++;
// show user new list of saved messages.
await turnContext.SendActivityAsync($"{logItems.TurnNumber}: The list is now: {string.Join(", ", logItems.UtteranceList)}");
// Create Dictionary object to hold new list of messages.
var changes = new Dictionary<string, object>();
{
changes.Add("UtteranceLog", logItems);
};
try
{
// Save new list to your Storage.
await _myStorage.WriteAsync(changes,cancellationToken);
}
catch
{
// Inform the user an error occurred.
await turnContext.SendActivityAsync("Sorry, something went wrong storing your message!");
}
}
}
}
Avviare il bot
Eseguire il bot in locale.
Avviare l'emulatore e connettere il bot
Installare Bot Framework Emulator Next, avviare l'emulatore e quindi connettersi al bot nell'emulatore:
- Selezionare il collegamento Crea nuova configurazione bot nella scheda Benvenuto dell'emulatore.
- Compilare i campi per la connessione al bot, in base alle informazioni nella pagina Web visualizzata all'avvio del bot.
Interagire con il bot
Inviare un messaggio al bot. Il bot elencherà i messaggi ricevuti.
La parte restante di questo articolo illustra come salvare l'archiviazione permanente anziché la memoria interna del bot.
Uso di Cosmos DB
Importante
La classe CosmosDbStorage è stata deprecata. I contenitori creati in origine con CosmosDbStorage non avevano set di chiavi di partizione e avevano la chiave di partizione predefinita di _/partitionKey.
I contenitori creati con l'archiviazione cosmos DB possono essere usati con l'archiviazione partizionata di Cosmos DB. Per altre informazioni, vedere Partizionamento in Azure Cosmos DB.
Si noti anche che, a differenza dell'archiviazione di Cosmos DB legacy, l'archiviazione partizionata di Cosmos DB non crea automaticamente un database all'interno dell'account Cosmos DB. È necessario creare manualmente un nuovo database, ma ignorare la creazione manuale di un contenitore perché CosmosDbPartitionedStorage creerà automaticamente il contenitore.
Ora che è stata usata l'archiviazione in memoria, è possibile aggiornare il codice in modo da usare Azure Cosmos DB. Cosmos DB è il database multimodello di Microsoft distribuito a livello globale. Azure Cosmos DB garantisce la scalabilità elastica e indipendente della velocità effettiva e dello spazio di archiviazione tra un numero qualsiasi di aree geografiche di Azure. Offre garanzie di produttività, latenza, disponibilità e coerenza con contratti di servizio completi.
Configurare una risorsa cosmos DB
Per usare Cosmos DB nel bot, è necessario creare una risorsa di database prima di affrontare il codice. Per una descrizione approfondita del database e della creazione di app cosmos DB, vedere la guida introduttiva per .NET, Node.js o Python.
Creare l'account del database
Passare al portale di Azure per creare un account Azure Cosmos DB. Cercare e selezionare Azure Cosmos DB.
Nella pagina Azure Cosmos DB selezionare Nuovo per visualizzare la pagina Crea account Azure Cosmos DB.
Fornire i valori per i campi seguenti:
- Sottoscrizione. Selezionare la sottoscrizione di Azure da usare per l'account Azure Cosmos.
- Gruppo di risorse. Selezionare un gruppo di risorse esistente o selezionare Crea nuovo e immettere un nome per un nuovo gruppo di risorse.
- Nome account. Immettere un nome per identificare l'account Azure Cosmos. Dato che al nome specificato viene aggiunto documents.azure.com per creare l'URI, usare un nome univoco. Si notino le linee guida seguenti:
- Il nome deve essere univoco in Azure.
- Il nome deve avere una lunghezza compresa tra 3 e 31 caratteri.
- Il nome può includere solo lettere minuscole, numeri e il trattino (-).
- API. Selezionare Core(SQL)
- Posizione. selezionare una posizione più vicina agli utenti per concedere loro l'accesso più rapido ai dati.
Selezionare Rivedi e crea.
Dopo la convalida, selezionare Crea.
La creazione dell'account richiede alcuni minuti. Attendere che nel portale venga visualizzata la pagina Complimenti, l'account Azure Cosmos DB è stato creato.
Aggiungi un database
Nota
Non creare il contenitore manualmente. Il bot lo creerà automaticamente durante la creazione del client Cosmos DB interno, assicurandosi che sia configurato correttamente per l'archiviazione dello stato del bot.
Passare alla pagina Esplora dati all'interno dell'account Cosmos DB appena creato, quindi scegliere Nuovo database dall'elenco a discesa Nuovo contenitore. Verrà quindi aperto un pannello sul lato destro della finestra, in cui è possibile immettere i dettagli per il nuovo database.
Immettere un ID per il nuovo database e, facoltativamente, impostare la velocità effettiva (è possibile modificarla in un secondo momento) e infine selezionare OK per creare il database. Prendere nota di questo ID database per usarlo in seguito durante la configurazione del bot.
Dopo aver creato un account Cosmos DB e un database, è necessario copiare alcuni dei valori per l'integrazione del nuovo database nel bot. Per recuperarli, passare alla scheda Chiavi nella sezione delle impostazioni del database dell'account Cosmos DB. Da questa pagina sono necessari l'URI (endpoint Cosmos DB) e la chiave primaria (chiave di autorizzazione).
È ora necessario avere un account Cosmos DB con un database e i valori seguenti pronti per l'uso nelle impostazioni del bot.
- URI
- Chiave primaria
- ID database
Aggiungere informazioni di configurazione di Cosmos DB
Usare i dettagli annotato nella parte precedente di questo articolo per impostare l'endpoint, la chiave di autorizzazione e l'ID del database. È infine necessario scegliere un nome appropriato per il contenitore che verrà creato nel database e in cui verrà archiviato lo stato del bot. Nell'esempio seguente il contenitore Cosmos DB creato verrà denominato "bot-storage".
Aggiungere le informazioni seguenti al file di configurazione.
appsettings.json
"CosmosDbEndpoint": "<your-CosmosDb-URI>",
"CosmosDbAuthKey": "<your-primary-key>",
"CosmosDbDatabaseId": "<your-database-id>",
"CosmosDbContainerId": "bot-storage"
Installazione di pacchetti Cosmos DB
Assicurarsi di avere i pacchetti necessari per Cosmos DB.
Installare il pacchetto NuGet Microsoft.Bot.Builder.Azure . Per altre informazioni sull'uso di NuGet, vedere Installare e gestire pacchetti in Visual Studio usando NuGet Gestione pacchetti .
Implementazione di Cosmos DB
Nota
Nella versione 4.6 è stato introdotto un nuovo provider di archiviazione Cosmos DB, ovvero la classe CosmosDbPartitionedStorage, mentre la classe CosmosDbStorage originale è stata deprecata. I contenitori creati con l'archiviazione cosmos DB possono essere usati con l'archiviazione partizionata di Cosmos DB. Per altre informazioni, vedere Partizionamento in Azure Cosmos DB.
A differenza dell'archiviazione di Cosmos DB legacy, l'archiviazione partizionata di Cosmos DB non crea automaticamente un database all'interno dell'account Cosmos DB. È necessario creare manualmente un nuovo database, ma ignorare la creazione manuale di un contenitore perché CosmosDbPartitionedStorage creerà automaticamente il contenitore.
Il codice di esempio seguente viene eseguito usando lo stesso codice bot dell'esempio di archiviazione di memoria fornito in precedenza, con le eccezioni elencate di seguito. I frammenti di codice seguenti mostrano un'implementazione dell'archiviazione di Cosmos DB per "myStorage" che sostituisce l'archiviazione di memoria locale.
È prima necessario aggiornare Startup.cs per fare riferimento alla libreria di Azure di Bot Builder:
using Microsoft.Bot.Builder.Azure;
Successivamente, nel ConfigureServices
metodo in Startup.cs, creare l'oggetto CosmosDbPartitionedStorage
. Verrà passato al costruttore tramite l'inserimento EchoBot
delle dipendenze.
// Use partitioned CosmosDB for storage, instead of in-memory storage.
services.AddSingleton<IStorage>(
new CosmosDbPartitionedStorage(
new CosmosDbPartitionedStorageOptions
{
CosmosDbEndpoint = Configuration.GetValue<string>("CosmosDbEndpoint"),
AuthKey = Configuration.GetValue<string>("CosmosDbAuthKey"),
DatabaseId = Configuration.GetValue<string>("CosmosDbDatabaseId"),
ContainerId = Configuration.GetValue<string>("CosmosDbContainerId"),
CompatibilityMode = false,
}));
In EchoBot.cs modificare la dichiarazione private static readonly MemoryStorage _myStorage = new MemoryStorage();
della _myStorage
variabile nel modo seguente:
// variable used to save user input to CosmosDb Storage.
private readonly IStorage _myStorage;
Passare quindi l'oggetto IStorage
al EchoBot
costruttore:
public EchoBot(IStorage storage)
{
if (storage is null) throw new ArgumentNullException();
_myStorage = storage;
}
Avviare il bot cosmos DB
Eseguire il bot in locale.
Testare il bot Cosmos DB con Bot Framework Emulator
Avviare Bot Framework Emulator e connettersi al bot:
- Selezionare il collegamento Crea una nuova configurazione del bot nella scheda Benvenuto dell'emulatore.
- Compilare i campi per la connessione al bot, in base alle informazioni nella pagina Web visualizzata all'avvio del bot.
Interagire con il bot cosmos DB
Inviare un messaggio al bot, che elencherà i messaggi ricevuti.
Visualizzare i dati di Cosmos DB
Dopo aver eseguito il bot e salvato le informazioni, è possibile visualizzare i dati archiviati nella portale di Azure nella scheda Esplora dati.
Uso dell'archiviazione BLOB
L'archivio BLOB di Azure è la soluzione di archiviazione di oggetti Microsoft per il cloud. L'archiviazione BLOB è ottimizzata per l'archiviazione di grandi quantità di dati non strutturati, ad esempio testo o dati binari. Questa sezione illustra come creare un account di archiviazione BLOB di Azure e un contenitore, quindi come fare riferimento al contenitore di archiviazione BLOB dal bot.
Per altre informazioni sull'archiviazione BLOB, vedere Che cos'è l'archiviazione BLOB di Azure?
Creare l'account di archiviazione BLOB
Per usare l'archiviazione BLOB nel bot, è necessario eseguire alcune configurazioni prima di affrontare il codice.
Nel portale di Azure selezionare Tutti i servizi.
Nella sezione In primo piano della pagina Tutti i servizi selezionare Account di archiviazione.
Nella pagina Account di archiviazione selezionare Nuovo.
Nella campo Sottoscrizione selezionare la sottoscrizione in cui creare l'account di archiviazione.
Nel campo Gruppo di risorse selezionare un gruppo di risorse esistente o selezionare Crea nuovo e immettere un nome per il nuovo gruppo di risorse.
Nel campo Nome account di archiviazione immettere un nome per l'account. Tenere presenti le linee guida seguenti:
- Il nome deve essere univoco in Azure.
- Il nome deve avere una lunghezza compresa tra 3 e 24 caratteri.
- Il nome può includere solo numeri e lettere minuscole.
Nel campo Posizione selezionare una posizione per l'account di archiviazione o usare la posizione predefinita.
Per il resto delle impostazioni, configurare quanto segue:
- Prestazioni: Standard. Altre informazioni sulle prestazioni.
- Tipo di account: BlobStorage. Altre informazioni sugli account di archiviazione.
- Replica: lasciare l'impostazione predefinita. Altre informazioni sulla ridondanza.
Nella sezione Dettagli progetto della pagina Crea account di archiviazione selezionare i valori desiderati per sottoscrizione e Gruppo di risorse.
Nella sezione Dettagli istanza della pagina Crea account di archiviazione immettere il nome dell'account di archiviazione e quindi selezionare i valori per Località, Tipo di account e Replica.
Selezionare Rivedi e crea per controllare le impostazioni dell'account di archiviazione.
Dopo la convalida, selezionare Crea.
Creare il contenitore di archiviazione BLOB
Dopo aver creato l'account di archiviazione BLOB, aprirlo, quindi:
Selezionare Storage Explorer (anteprima).
Fare quindi clic con il pulsante destro del mouse su CONTENITORI BLOB
Selezionare Crea contenitore BLOB dall'elenco a discesa.
Immettere un nome nel modulo Nuovo contenitore . Questo nome verrà usato per il valore del "nome del contenitore BLOB" per fornire l'accesso all'account di archiviazione BLOB. Tenere presenti le linee guida seguenti:
- Questo nome può contenere solo lettere minuscole, numeri e trattini.
- Questo nome deve iniziare con una lettera o un numero.
- Ogni trattino deve essere preceduto e seguito da un carattere non trattino valido.
- Il nome deve avere una lunghezza compresa tra 3 e 63 caratteri.
Aggiungere informazioni di configurazione dell'archiviazione BLOB
Trovare le chiavi di archiviazione BLOB necessarie per configurare l'archiviazione BLOB per il bot, come illustrato in precedenza:
- Nella portale di Azure aprire l'account di archiviazione BLOB e selezionare Chiavi di accesso nella sezione Impostazioni.
- Per configurare il bot per l'accesso all'account di archiviazione BLOB, usare Stringa di connessione come valore per il BLOB stringa di connessione.
Aggiungere le informazioni seguenti al file di configurazione.
appsettings.json
"BlobConnectionString": "<your-blob-connection-string>",
"BlobContainerName": "<your-blob-container-name>",
Installazione di pacchetti di archiviazione BLOB
Se non è installato in precedenza, installare i pacchetti seguenti.
Installare il pacchetto NuGet Microsoft.Bot.Builder.Azure.Blobs . Per altre informazioni sull'uso di NuGet, vedere Installare e gestire pacchetti in Visual Studio usando il Gestione pacchetti NuGet.
Implementazione dell'archiviazione BLOB
L'archiviazione BLOB viene usata per archiviare lo stato del bot.
Nota
A partire dalla versione 4.10, Microsoft.Bot.Builder.Azure.AzureBlobStorage
è deprecato. Usare il nuovo Microsoft.Bot.Builder.Azure.Blobs.BlobsStorage
al suo posto.
Il codice di esempio seguente viene eseguito usando lo stesso codice bot dell'esempio di archiviazione di memoria fornito in precedenza, con le eccezioni elencate di seguito.
I frammenti di codice seguenti mostrano un'implementazione dell'archivio BLOB per "myStorage" che sostituisce l'archiviazione di memoria locale.
È prima necessario aggiornare Startup.cs per fare riferimento alla libreria BLOB di Azure di Bot Builder:
Startup.cs
using Microsoft.Bot.Builder.Azure.Blobs;
Successivamente, nel metodo in ConfigureServices
Startup.cs creare l'oggetto BlobsStorage
passando i valori da appsettings.json
. Verrà passato al costruttore tramite l'inserimento EchoBot
delle dipendenze.
//Use Azure Blob storage, instead of in-memory storage.
services.AddSingleton<IStorage>(
new BlobsStorage(
Configuration.GetValue<string>("BlobConnectionString"),
Configuration.GetValue<string>("BlobContainerName")
));
È prima necessario aggiornare EchoBot.cs per fare riferimento alla libreria BLOB di Azure di Bot Builder:
EchoBot.cs
using Microsoft.Bot.Builder.Azure.Blobs;
Rimuovere o impostare come commento la riga di codice che crea la variabile MemoryStorage 'private static readonly MemoryStorage _myStorage = new MemoryStorage();' e creare una nuova variabile che verrà usata per salvare l'input dell'utente nell'archivio BLOB.
EchoBot.cs
// variable used to save user input to CosmosDb Storage.
private readonly IStorage _myStorage;
Passare quindi l'oggetto IStorage
al EchoBot
costruttore:
public EchoBot(IStorage storage)
{
if (storage is null) throw new ArgumentNullException();
_myStorage = storage;
}
Dopo aver impostato l'archiviazione in modo che punti all'account di archiviazione BLOB, il codice del bot archivierà e recupererà i dati dall'archivio BLOB.
Dopo aver impostato l'archiviazione in modo che punti all'account di archiviazione BLOB, il codice del bot archivierà e recupererà i dati dall'archivio BLOB.
Avviare il bot di archiviazione BLOB
Eseguire il bot in locale.
Avviare l'emulatore e connettere il bot di archiviazione BLOB
Avviare quindi l'emulatore e quindi connettersi al bot nell'emulatore:
- Selezionare il collegamento Crea nuova configurazione bot nella scheda "Benvenuto" dell'emulatore.
- Compilare i campi per la connessione al bot, in base alle informazioni nella pagina Web visualizzata all'avvio del bot.
Interagire con il bot di archiviazione BLOB
Inviare un messaggio al bot, che elencherà i messaggi ricevuti.
Visualizzare i dati di archiviazione BLOB
Dopo aver eseguito il bot e salvato le informazioni, è possibile visualizzarla nella scheda Storage Explorer del portale di Azure.
Archiviazione trascrizioni BLOB
L'archiviazione trascrizioni BLOB di Azure offre un'opzione di archiviazione specializzata che permette di salvare e recuperare facilmente le conversazioni degli utenti sotto forma di trascrizione registrata. L'archiviazione di trascrizioni BLOB di Azure è utile per acquisire automaticamente gli input utente da esaminare durante il debug delle prestazioni del bot.
Nota
Python attualmente non supporta l'archiviazione trascrizioni BLOB di Azure. Mentre JavaScript supporta l'archiviazione trascrizioni BLOB, le indicazioni seguenti sono solo per C#.
Configurare un contenitore di archiviazione trascrizioni BLOB
L'archiviazione trascrizioni BLOB di Azure può usare lo stesso account di archiviazione BLOB creato seguendo i passaggi descritti nelle sezioni "Creare l'account di archiviazione BLOB" e "Aggiungere informazioni di configurazione" precedenti. Aggiungere ora un contenitore in cui inserire le trascrizioni
- Aprire l'account di archiviazione BLOB di Azure.
- Selezionare Storage Explorer.
- Fare clic con il pulsante destro del mouse su BLOB CONTAINERS (CONTENITORI BLOB) e selezionare Create Blob Container (Crea contenitore BLOB).
- Immettere un nome per il contenitore di trascrizioni e quindi selezionare OK. (Abbiamo immesso mybottranscripts)
Implementazione dell'archiviazione trascrizioni BLOB
Il codice seguente consente di connettere il puntatore dell'archiviazione trascrizioni _myTranscripts
al nuovo account di archiviazione trascrizioni BLOB di Azure. Per creare questo collegamento con un nuovo nome di contenitore, <your-blob-transcript-container-name>, crea un nuovo contenitore all'interno dell'archivio BLOB per contenere i file di trascrizione.
L'archiviazione trascrizioni BLOB è progettata per archiviare le trascrizioni dei bot.
Nota
A partire dalla versione 4.10, Microsoft.Bot.Builder.Azure.AzureBlobTranscriptStore
è deprecato. Usare il nuovo Microsoft.Bot.Builder.Azure.Blobs.BlobsTranscriptStore
al suo posto.
echoBot.cs
using Microsoft.Bot.Builder.Azure.Blobs;
public class EchoBot : ActivityHandler
{
...
private readonly BlobsTranscriptStore _myTranscripts = new BlobsTranscriptStore("<your-azure-storage-connection-string>", "<your-blob-transcript-container-name>");
...
}
Archiviare le conversazioni utente nelle trascrizioni BLOB di Azure
Dopo che un contenitore BLOB è disponibile per archiviare le trascrizioni, è possibile iniziare a mantenere le conversazioni degli utenti con il bot. Queste conversazioni possono essere usate successivamente come strumento di debug per esaminare l'interazione tra utenti e bot. Ogni conversazione di riavvio dell'emulatore avvia la creazione di un nuovo elenco di conversazioni trascrizioni. Il codice seguente consente di mantenere gli input di conversazione degli utenti all'interno di un file di trascrizione archiviato.
- La trascrizione corrente viene salvata con
LogActivityAsync
. - Le trascrizioni salvate vengono recuperate con
ListTranscriptsAsync
. In questo codice di esempio l'ID di ogni trascrizione archiviata viene salvato in un elenco denominato "storedTranscripts". Questo elenco viene usato più avanti per gestire il numero di trascrizioni BLOB archiviate che vengono mantenute.
echoBot.cs
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
await _myTranscripts.LogActivityAsync(turnContext.Activity);
List<string> storedTranscripts = new List<string>();
PagedResult<Microsoft.Bot.Builder.TranscriptInfo> pagedResult = null;
var pageSize = 0;
do
{
pagedResult = await _myTranscripts.ListTranscriptsAsync("emulator", pagedResult?.ContinuationToken);
pageSize = pagedResult.Items.Count();
// transcript item contains ChannelId, Created, Id.
// save the channelIds found by "ListTranscriptsAsync" to a local list.
foreach (var item in pagedResult.Items)
{
storedTranscripts.Add(item.Id);
}
} while (pagedResult.ContinuationToken != null);
...
}
Gestire le trascrizioni BLOB archiviate
Anche se è possibile usare le trascrizioni archiviate come strumento di debug, nel tempo il numero di trascrizioni archiviate può aumentare notevolmente e raggiungere dimensioni superiori a quelle che si intende mantenere. Il codice aggiuntivo incluso di seguito usa DeleteTranscriptAsync
per rimuovere tutte le trascrizioni, ad eccezione delle ultime tre, dall'archivio trascrizioni BLOB.
echoBot.cs
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
await _myTranscripts.LogActivityAsync(turnContext.Activity);
List<string> storedTranscripts = new List<string>();
PagedResult<Microsoft.Bot.Builder.TranscriptInfo> pagedResult = null;
var pageSize = 0;
do
{
pagedResult = await _myTranscripts.ListTranscriptsAsync("emulator", pagedResult?.ContinuationToken);
pageSize = pagedResult.Items.Count();
// transcript item contains ChannelId, Created, Id.
// save the channelIds found by "ListTranscriptsAsync" to a local list.
foreach (var item in pagedResult.Items)
{
storedTranscripts.Add(item.Id);
}
} while (pagedResult.ContinuationToken != null);
// Manage the size of your transcript storage.
for (int i = 0; i < pageSize; i++)
{
// Remove older stored transcripts, save just the last three.
if (i < pageSize - 3)
{
string thisTranscriptId = storedTranscripts[i];
try
{
await _myTranscripts.DeleteTranscriptAsync("emulator", thisTranscriptId);
}
catch (System.Exception ex)
{
await turnContext.SendActivityAsync("Debug Out: DeleteTranscriptAsync had a problem!");
await turnContext.SendActivityAsync("exception: " + ex.Message);
}
}
}
...
}
Per altre informazioni sulla classe , vedere Archiviazione trascrizioni BLOB di Azure.
Informazioni aggiuntive
Gestire la concorrenza tramite eTag
Nell'esempio di codice del bot viene impostata la eTag
proprietà di ogni IStoreItem
su *
. Il membro eTag
(tag di entità) dell'oggetto archivio viene usato in Cosmos DB per gestire la concorrenza. eTag
indica al database che cosa fare se un'altra istanza del bot ha modificato l'oggetto nella stessa risorsa di archiviazione in cui sta scrivendo il bot.
Precedenza all'ultima scrittura - consentire la sovrascrittura
Un valore della proprietà eTag
di asterisco (*
) indica che l'ultima scrittura prevale. Quando si crea un nuovo archivio dati, è possibile impostare eTag
una proprietà su per *
indicare che non sono stati salvati in precedenza i dati scritti o che si desidera che l'ultimo writer sovrascriva qualsiasi proprietà salvata in precedenza. Se la concorrenza non è un problema per il bot, impostare la eTag
proprietà su *
per tutti i dati scritti abilita la sovrascrittura.
Gestire la concorrenza e impedire la sovrascrittura
Nell'archiviare i dati in Cosmos DB, usare un valore diverso da *
per eTag
se si vuole impedire l'accesso simultaneo a una proprietà, per evitare di sovrascrivere le modifiche apportate da un'altra istanza del bot. Il bot riceve una risposta di errore con il messaggio etag conflict key=
quando tenta di salvare i dati sullo stato e non eTag
è lo stesso valore di nell'archiviazione eTag
.
Per impostazione predefinita, l'archivio Cosmos DB controlla la proprietà eTag
di un oggetto di archiviazione per verificarne l'uguaglianza ogni volta che un bot scrive in questo elemento e quindi lo aggiorna con un nuovo valore univoco dopo ogni scrittura. Se la proprietà eTag
durante la scrittura non corrisponde al valore eTag
nella risorsa di archiviazione, significa che un altro bot o thread ha modificato i dati.
Si supponga, ad esempio, che il bot debba modificare una nota salvata, ma che non debba sovrascrivere le modifiche eseguite da un'altra istanza del bot. Se un'altra istanza del bot ha apportato modifiche, l'utente dovrà modificare la versione con gli aggiornamenti più recenti.
In primo luogo, creare una classe che implementi IStoreItem
.
EchoBot.cs
public class Note : IStoreItem
{
public string Name { get; set; }
public string Contents { get; set; }
public string ETag { get; set; }
}
Successivamente, creare una nota iniziale mediante la creazione di un oggetto di archiviazione e aggiungere l'oggetto all'archivio.
EchoBot.cs
// create a note for the first time, with a non-null, non-* ETag.
var note = new Note { Name = "Shopping List", Contents = "eggs", ETag = "x" };
var changes = Dictionary<string, object>();
{
changes.Add("Note", note);
};
await NoteStore.WriteAsync(changes, cancellationToken);
Quindi, accedere e aggiornare la nota in un secondo momento, mantenendo il valore eTag
letto dall'archivio.
EchoBot.cs
var note = NoteStore.ReadAsync<Note>("Note").Result?.FirstOrDefault().Value;
if (note != null)
{
note.Contents += ", bread";
var changes = new Dictionary<string, object>();
{
changes.Add("Note1", note);
};
await NoteStore.WriteAsync(changes, cancellationToken);
}
Se la nota è stata aggiornata nell'archivio prima di scrivere le modifiche, la chiamata a Write
genera un'eccezione.
Per mantenere la concorrenza, leggere sempre una proprietà dalla risorsa di archiviazione, quindi modificare la proprietà di lettura in modo che eTag
venga mantenuto. Se si leggono i dati dell'utente dall'archivio, la risposta conterrà la proprietà eTag. Se si modificano i dati e si scrivono i dati aggiornati nell'archivio, la richiesta includerà la proprietà eTag che specifica lo stesso valore letto in precedenza. Tuttavia, la scrittura di un oggetto con il relativo valore eTag
impostato su *
consentirà di sovrascrivere tutte le altre modifiche.
Passaggi successivi
Ora che si è appreso come leggere e scrivere direttamente dall'archiviazione, è possibile esaminare come usare il gestore di stato per farlo.