스토리지에 직접 작성Write directly to storage

적용 대상: SDK v4APPLIES TO: SDK v4

미들웨어 또는 컨텍스트 개체를 사용하지 않고 스토리지 개체를 직접 읽고 작성할 수 있습니다.You can read and write directly to your storage object without using middleware or context object. 이는 봇에서 대화를 보존하는 데 사용하는 데이터 또는 봇의 대화 흐름 외부 소스에서 제공되는 데이터에 적합할 수 있습니다.This can be appropriate for data your bot uses to preserve a conversation, or data that comes from a source outside your bot's conversation flow. 이 데이터 스토리지 모델에서 데이터는 상태 관리자를 사용하는 대신 스토리지에서 직접 읽습니다.In this data storage model, data is read in directly from storage instead of using a state manager. 이 문서의 코드 예제에서는 메모리, Cosmos DB, Azure Blob 및 Azure Blob 기록 스토리지를 사용하여 데이터를 읽고 스토리지에 쓰는 방법을 보여 드립니다.The code examples in this article show you how to read and write data to storage using memory, Cosmos DB, Azure Blob, and Azure Blob transcript storage.

필수 구성 요소Prerequisites

참고

VSIX 패키지에는 .net core 2.1 및 .net core 3.1 버전의 c # 템플릿이 모두 포함 되어 있습니다.The VSIX package includes both .NET Core 2.1 and .NET Core 3.1 versions of the C# templates. Visual Studio 2019에서 새 봇을 만들 때는 .NET Core 3.1 템플릿을 사용해야 합니다.When creating new bots in Visual Studio 2019, you should use the .NET Core 3.1 templates. 현재 봇 샘플에서는 .NET Core 3.1 템플릿을 사용합니다.The current bot samples use .NET Core 3.1 templates. BotBuilder-Samples 리포지토리의 4.7-archive 분기에서 .NET Core 2.1 템플릿을 사용하는 샘플을 찾을 수 있습니다.You can find the samples that use .NET Core 2.1 templates in the 4.7-archive branch of the BotBuilder-Samples repository. Azure에 .NET Core 3.1 봇을 배포 하는 방법에 대 한 자세한 내용은 azure에 봇을 배포하는 방법을 참조 하세요.For information about deploying .NET Core 3.1 bots to Azure, see how to deploy your bot to Azure.

이 샘플 정보About this sample

이 문서의 샘플 코드는 기본 에코 봇의 구조로 시작한 다음, 아래에 나와 있는 코드를 추가하여 봇의 기능을 확장합니다.The sample code in this article begins with the structure of a basic echo bot, then extends that bot's functionality by adding additional code (provided below). 이러한 확장 코드는 수신된 사용자 입력을 저장할 목록을 만듭니다.This extended code creates a list to preserve user inputs as they are received. 각 턴마다 메모리에 저장된 사용자 입력의 전체 목록이 사용자에게 다시 에코됩니다.Each turn, the full list of user inputs, saved to memory, is echoed back to the user. 이 입력 목록을 포함하는 데이터 구조는 스토리지에 저장하도록 수정됩니다.The data structure containing this list of inputs is then modified to save to storage. 이 샘플 코드에 추가 기능이 추가되면 다양한 유형의 스토리지가 탐색됩니다.Various types of storage are explored as additional functionality is added to this sample code.

메모리 스토리지Memory storage

Bot Framework SDK를 사용하면 메모리 내 스토리지를 사용하여 사용자 입력을 저장할 수 있습니다.The Bot Framework SDK allows you to store user inputs using in-memory storage. 메모리 내 스토리지는 봇이 다시 시작될 때마다 지워지므로 테스트 목적에 가장 적합하며 프로덕션 용도로는 적합하지 않습니다.Since in-memory storage is cleared each time the bot is restarted, it is best suited for testing purposes and is not intended for production use. 데이터베이스 스토리지 같은 영구 스토리지 형식은 프로덕션 봇에 가장 적합합니다.Persistent storage types, such as database storage, are best for production bots.

기본 봇 빌드Build a basic bot

이 항목의 나머지에서는 Echo 봇을 빌드합니다.The rest of this topic builds off of an Echo bot. Echo 봇 샘플 코드는 C#, JavaScript 또는 Python에서 EchoBot을 빌드하기 위한 빠른 시작 지침에 따라 로컬로 빌드할 수 있습니다.The Echo bot sample code can be locally built by following the Quickstart instructions for building the EchoBot in either C#, JavaScript or Python.

EchoBot.cs의 코드를 다음 코드로 바꿉니다.Replace the code in EchoBot.cs with the following code:

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!");
         }
      }
   }
}

봇 시작Start your bot

봇을 로컬로 실행합니다.Run your bot locally.

Emulator 시작 및 봇 연결Start the Emulator and connect your bot

다음에 Bot Framework 에뮬레이터를 설치하고 에뮬레이터를 시작한 다음 에뮬레이터에서 봇에 연결합니다.Install the Bot Framework Emulator Next, start the Emulator and then connect to your bot in the Emulator:

  1. 에뮬레이터 시작 탭에서 새 봇 구성 만들기 링크를 선택합니다.Select the Create new bot configuration link in the Emulator Welcome tab.
  2. 봇을 시작할 때 표시되는 웹 페이지의 정보를 고려하여 필드를 채워 봇에 연결합니다.Fill in fields to connect to your bot, given the information on the webpage displayed when you started your bot.

봇과의 상호 작용Interact with your bot

봇에게 메시지를 보냅니다.Send a message to your bot. 봇이 수신된 메시지를 나열합니다.The bot will list the messages it has received.

에뮬레이터 테스트 스토리지 봇

이 문서의 나머지 부분에서는 봇의 내부 메모리 대신 영구 스토리지에 저장하는 방법을 보여줍니다.The remainder of this article will demonstrate how to save to persistent storage instead of the bot's internal memory.

Cosmos DB 사용Using Cosmos DB

중요

Cosmos DB 스토리지 클래스는 더 이상 사용되지 않습니다.The Cosmos DB storage class has been deprecated. 원래 CosmosDbStorage를 사용하여 만든 컨테이너에는 파티션 키 집합이 없으며 _ partitionKey 의 기본 파티션 키가 / 지정되었습니다.Containers originally created with CosmosDbStorage had no partition key set, and were given the default partition key of _/partitionKey.

Cosmos DB 스토리지를 사용하여 만든 컨테이너는 Cosmos DB 분할된 스토리지 와 함께 사용할 수 있습니다.Containers created with Cosmos DB storage can be used with Cosmos DB partitioned storage. 자세한 내용은 Azure Cosmos DB 분할을 읽어보세요.Read Partitioning in Azure Cosmos DB for more information.

또한 레거시 Cosmos DB 스토리지와 달리 Cosmos DB 분할된 스토리지는 Cosmos DB 계정 내에 데이터베이스를 자동으로 만들지 않습니다.Also note that, unlike the legacy Cosmos DB storage, the Cosmos DB partitioned storage does not automatically create a database within your Cosmos DB account. 새 데이터베이스를 수동으로 만들어야하지만 CosmosDbPartitionedStorage가 컨테이너를 만들므로 수동으로 컨테이너 만들기를 건너뜁니다.You need to create a new database manually, but skip manually creating a container since CosmosDbPartitionedStorage will create the container for you.

이제 메모리 스토리지를 사용했으므로 Azure Cosmos DB를 사용하도록 코드를 업데이트합니다.Now that you've used memory storage, we'll update the code to use Azure Cosmos DB. Cosmos DB는 전 세계에 배포된 Microsoft의 멀티모델 데이터베이스입니다.Cosmos DB is Microsoft's globally distributed, multi-model database. Azure Cosmos DB를 사용하면 Azure의 여러 지리적 영역에서 처리량 및 스토리지를 탄력적이고 독립적으로 크기 조정할 수 있습니다.Azure Cosmos DB enables you to elastically and independently scale throughput and storage across any number of Azure's geographic regions. 포괄적인 SLA(서비스 수준 계약)를 통해 처리량, 대기 시간, 가용성 및 일관성을 보장합니다.It offers throughput, latency, availability, and consistency guarantees with comprehensive service level agreements (SLAs).

Cosmos DB 리소스 설정Set up a Cosmos DB resource

봇에서 Cosmos DB를 사용하려면 코드에 가져오기 전에 데이터베이스 리소스를 만들어야 합니다.To use Cosmos DB in your bot, you'll need to create a database resource before getting into the code. Cosmos DB 데이터베이스 및 앱 만들기에 대한 자세한 설명은 .Net, Node.js 또는 Python에 대한 빠른 시작 을 참조하세요.For an in-depth description of Cosmos DB database and app creation, see the quickstart for .Net, Node.js or Python.

데이터베이스 계정 만들기Create your database account

  1. Azure Portal로 이동하여 Azure Cosmos DB 계정을 만듭니다.Go to the Azure portal to create an Azure Cosmos DB account. Azure Cosmos DB 를 검색하여 선택합니다.Search for and select Azure Cosmos DB.

  2. Azure Cosmos DB 페이지에서 새로 만들기를 선택하여 Azure Cosmos DB 계정 만들기 페이지를 표시합니다.In the Azure Cosmos DB page, select New to bring up the the Create Azure Cosmos DB Account page.

    Cosmos DB 데이터베이스 계정 만들기

  3. 다음 필드에 대한 값을 제공합니다.Provide values for the following fields:

    1. 구독.Subscription. 이 Azure Cosmos 계정에 사용하려는 Azure 구독을 선택합니다.Select the Azure subscription that you want to use for this Azure Cosmos account.
    2. 리소스 그룹.Resource group. 기존 리소스 그룹을 선택하거나 새 만들기를 선택하고 새 리소스 그룹의 이름을 입력합니다.Select an existing resource group or select Create new, and enter a name for a new resource group.
    3. 계정 이름 입니다.Account name. Azure Cosmos 계정을 식별하는 이름을 입력합니다.Enter a name to identify your Azure Cosmos account. URI를 만들기 위해 제공하는 이름에 documents.azure.com 이 추가되므로 고유한 이름을 사용합니다.Because documents.azure.com is appended to the name that you provide to create your URI, use a unique name. 다음 지침에 유의하세요.Note the following guidelines:
      • 이름은 Azure에서 고유해야 합니다.The name must be unique across Azure.
      • 이름은 3자에서 31자 사이여야 합니다.The name must be between three and 31 characters long.
      • 이름은 소문자, 숫자 및 하이픈(-) 문자만 포함할 수 있습니다.The name can include only lowercase letters, numbers, and the hyphen (-) character.
    4. API.API. Core(SQL) 선택Select Core(SQL)
    5. 위치.Location. 사용자에게 가장 가까운 위치를 선택하여 데이터에 가장 빠르게 액세스할 수 있도록 합니다.select a location that is closest to your users to give them the fastest access to the data.
  4. 검토 + 만들기 를 선택합니다.Select Review + Create.

  5. 유효성이 검사되면 만들기를 선택합니다.Once validated, select Create.

계정 생성에는 몇 분 정도가 소요됩니다.The account creation takes a few minutes. 포털에서 축하합니다! Azure Cosmos DB 계정이 만들어졌습니다. 페이지가 표시될 때까지 기다립니다.Wait for the portal to display the Congratulations! Your Azure Cosmos DB account was created page.

데이터베이스 추가Add a database

참고

컨테이너는 직접 만들지 않아야 합니다.You should not create the container yourself. 내부 Cosmos DB 클라이언트를 만들 때 봇이 만들어져 봇 상태를 저장하도록 올바르게 구성됩니다.Your bot will create it for you when creating its internal Cosmos DB client, ensuring it is configured correctly for storing bot state.

  1. 새로 만든 Cosmos DB 계정 내의 데이터 탐색기 페이지로 이동한 다음 새 컨테이너 드롭다운에서 새 데이터베이스를 선택합니다.Navigate to the Data Explorer page within your newly created Cosmos DB account, then choose New Database from the New Container drop-down. 그러면 창의 오른쪽에 새 데이터베이스에 대한 세부 정보를 입력할 수 있는 패널이 열립니다.A panel will then open on the right hand side of the window, where you can enter the details for the new database.

    Cosmos DB 데이터베이스 리소스 이미지 만들기

  2. 새 데이터베이스에 대한 ID를 입력하고 필요에 따라 처리량을 설정하고(나중에 변경할 수 있습니다) 마지막으로 확인을 선택하여 데이터베이스를 만듭니다.Enter an ID for your new database and, optionally, set the throughput (you can change this later) and finally select OK to create your database. 나중에 봇을 구성할 때 사용할 수 있도록 이 데이터베이스의 ID를 적어 둡니다.Make a note of this database ID for use later on when configuring your bot.

  3. 이제 Cosmos DB 계정과 데이터베이스를 만들었으므로 새 데이터베이스를 봇에 통합하기 위해 몇 가지 값을 복사해야 합니다.Now that you have created a Cosmos DB account and a database, you need to copy over some of the values for integrating your new database into your bot. 이러한 항목을 검색하려면 Cosmos DB 계정의 데이터베이스 설정 섹션 내의 탭으로 이동합니다.To retrieve these, navigate to the Keys tab within the database settings section of your Cosmos DB account. 이 페이지에서 URI( Cosmos DB 엔드포인트)기본 키( 권한 부여 키)가 필요합니다.From this page you will need your URI (Cosmos DB endpoint) and your PRIMARY KEY (authorization key).

    Cosmos DB 키

이제 데이터베이스가 있는 Cosmos DB 계정과 봇 설정에서 사용할 준비가 된 다음 값이 있어야 합니다.You should now have a Cosmos DB account with a database and the following values ready to use in your bot settings.

  • URIURI
  • 기본 키Primary Key
  • 데이터베이스 IDDatabase ID

Cosmos DB 구성 정보 추가Add Cosmos DB configuration information

이 문서의 앞 부분에서 적어 둔 세부 정보를 사용하여 엔드포인트, 권한 부여 키 및 데이터베이스 ID를 설정합니다.Use the details you made a note of in the previous part of this article to set your endpoint, authorization key and database ID. 마지막으로, 봇 상태를 저장하기 위해 데이터베이스 내에 만들어질 컨테이너에 대한 적절한 이름을 선택해야 합니다.Finally, you should choose an appropriate name for the container that will be created within your database to store your bot state. 아래 예제에서 생성된 Cosmos DB 컨테이너의 이름은 "bot-storage"입니다.In the example below the Cosmos DB container that is created will be named "bot-storage".

구성 파일에 다음 정보를 추가합니다.Add the following information to your configuration file.

appsettings.jsonappsettings.json

"CosmosDbEndpoint": "<your-CosmosDb-URI>",
"CosmosDbAuthKey": "<your-primary-key>",
"CosmosDbDatabaseId": "<your-database-id>",
"CosmosDbContainerId": "bot-storage"

Cosmos DB 패키지 설치Installing Cosmos DB packages

Cosmos DB에 필요한 패키지가 있는지 확인합니다.Make sure you have the packages necessary for Cosmos DB.

Microsoft.Bot.Builder.Azure NuGet 패키지를 설치합니다.Install the Microsoft.Bot.Builder.Azure NuGet package. NuGet 사용에 대한 자세한 내용은 NuGet 패키지 관리자 사용하여 Visual Studio 패키지 설치 및 관리를 참조하세요.For more information on using NuGet, see Install and manage packages in Visual Studio using the NuGet Package Manager .

Cosmos DB 구현Cosmos DB implementation

참고

버전 4.6에는 새로운 Cosmos DB 스토리지 공급자, Cosmos DB 분할된 스토리지 클래스가 도입되었으며, 원래의 Cosmos DB 스토리지 클래스는 더 이상 사용되지 않습니다.Version 4.6 introduced a new Cosmos DB storage provider, the Cosmos DB partitioned storage class, and the original Cosmos DB storage class is deprecated. Cosmos DB 스토리지를 사용하여 만든 컨테이너는 Cosmos DB 분할된 스토리지 와 함께 사용할 수 있습니다.Containers created with Cosmos DB storage can be used with Cosmos DB partitioned storage. 자세한 내용은 Azure Cosmos DB 분할을 읽어보세요.Read Partitioning in Azure Cosmos DB for more information.

또한 레거시 Cosmos DB 스토리지와 달리 Cosmos DB 분할된 스토리지는 Cosmos DB 계정 내에 데이터베이스를 자동으로 만들지 않습니다.Also note that, unlike the legacy Cosmos DB storage, the Cosmos DB partitioned storage does not automatically create a database within your Cosmos DB account. 새 데이터베이스를 수동으로 만들어야하지만 CosmosDbPartitionedStorage가 컨테이너를 만들므로 수동으로 컨테이너 만들기를 건너뜁니다.You need to create a new database manually, but skip manually creating a container since CosmosDbPartitionedStorage will create the container for you.

다음 샘플 코드는 위에 나열된 예외를 제외하고 위에 제공된 메모리 스토리지 샘플과 동일한 봇 코드를 사용하여 실행됩니다.The following sample code runs using the same bot code as the memory storage sample provided above, with the exceptions listed here. 아래 코드 조각은 로컬 메모리 스토리지를 대체하는 'myStorage'에 대한 Cosmos DB 스토리지의 구현을 보여줍니다.The code snippets below show an implementation of Cosmos DB storage for 'myStorage' that replaces local Memory storage.

먼저 Bot Builder Azure 라이브러리를 참조하도록 Startup.cs를 업데이트해야 합니다.You first need to update Startup.cs to reference the bot builder Azure library:

using Microsoft.Bot.Builder.Azure;

다음으로 ConfigureServices Startup.cs의 메서드에서 CosmosDbPartitionedStorage 개체를 만듭니다.Next, in the ConfigureServices method in Startup.cs, create the CosmosDbPartitionedStorage object. EchoBot종속성 주입을 통해 생성자에 전달됩니다.This will be passed into the EchoBot constructor through dependency injection.

// 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,
        }));

EchoBot.cs에서 _myStorage 변수 선언을 다음으로 변경합니다. private static readonly MemoryStorage _myStorage = new MemoryStorage();In EchoBot.cs change the _myStorage variable declaration private static readonly MemoryStorage _myStorage = new MemoryStorage(); to the following:

// variable used to save user input to CosmosDb Storage.
private readonly IStorage _myStorage;

그런 다음 IStorage 개체를 생성자에 전달합니다. EchoBotThen pass in the IStorage object to the EchoBot constructor:

public EchoBot(IStorage storage)
{
    if (storage is null) throw new ArgumentNullException();
    _myStorage = storage;
}

Cosmos DB 봇 시작Start your Cosmos DB bot

봇을 로컬로 실행합니다.Run your bot locally.

Bot Framework Emulator Cosmos DB 봇 테스트Test your Cosmos DB bot with Bot Framework Emulator

이제 Bot Framework Emulator 시작하고 봇에 연결합니다.Now start the Bot Framework Emulator and connect to your bot:

  1. 에뮬레이터 시작 탭에서 새 봇 구성 만들기 링크를 선택합니다.Select the create a new bot configuration link in the Emulator Welcome tab.
  2. 봇을 시작할 때 표시되는 웹 페이지의 정보를 고려하여 필드를 채워 봇에 연결합니다.Fill in fields to connect to your bot, given the information on the webpage displayed when you started your bot.

Cosmos DB 봇과 상호 작용Interact with your Cosmos DB bot

봇에 메시지를 보내면 봇이 수신한 메시지를 나열합니다.Send a message to your bot, and the bot will list the messages it received. 에뮬레이터 실행Emulator running

Cosmos DB 데이터 보기View your Cosmos DB data

봇을 실행하고 정보를 저장한 후 데이터 탐색기 탭 아래의 Azure Portal에서 저장된 데이터를 볼 수 있습니다.After you have run your bot and saved your information, we can view the data stored in the Azure portal under the Data Explorer tab.

데이터 탐색기 예제

Blob Storage 사용Using Blob storage

Azure Blob Storage는 클라우드를 위한 Microsoft의 개체 스토리지 솔루션입니다.Azure Blob storage is Microsoft's object storage solution for the cloud. Blob Storage는 텍스트 또는 이진 데이터와 같이 구조화되지 않은 대량의 데이터를 저장하는 데 최적화되어 있습니다.Blob storage is optimized for storing massive amounts of unstructured data, such as text or binary data. 이 섹션에서는 Azure Blob Storage 계정 및 컨테이너를 만드는 방법, 봇에서 Blob Storage 컨테이너를 참조하는 방법을 설명합니다.This section explains how to create an Azure blob storage account and container, then how to reference your blob storage container from your bot.

Blob Storage 대한 자세한 내용은 Azure Blob Storage란?을 참조하세요.For additional information on Blob Storage, see What is Azure Blob storage?

Blob Storage 계정 만들기Create your Blob storage account

봇에서 Blob Storage를 사용하려면 코드를 살펴보기 전에 몇 가지 작업을 설정해야 합니다.To use Blob storage in your bot, you'll need to get a few things set up before getting into the code.

  1. Azure Portal에서 모든 서비스 를 선택합니다.In the Azure portal, select All services.

  2. 모든 서비스 페이지의 추천 섹션에서 스토리지 계정 을 선택합니다.In the Featured section of the All services page, select Storage accounts.

  3. 스토리지 계정 페이지에서 새로 사용 선택합니다.In the Storage accounts page, select **New****.

    Blob 스토리지 계정 만들기 페이지

  4. 구독 필드에서 스토리지 계정을 만들 구독을 선택합니다.In the Subscription field, select the subscription in which to create the storage account.

  5. 리소스 그룹 필드에서 기존 리소스 그룹을 선택하거나 새 리소스 그룹 만들기를 선택하고 새 리소스 그룹의 이름을 입력합니다.In the Resource group field, select an existing resource group or select Create new, and enter a name for the new resource group.

  6. 스토리지 계정 이름 필드에 계정 이름을 입력합니다.In the Storage account name field, enter a name for the account. 다음 지침에 유의하세요.Note the following guidelines:

    • 이름은 Azure에서 고유해야 합니다.The name must be unique across Azure.
    • 이름은 3자에서 24자 사이여야 합니다.The name must be between three and 24 characters long.
    • 이름에는 숫자와 소문자만 포함될 수 있습니다.The name can include only numbers and lowercase letters.
  7. 위치 필드에서 스토리지 계정의 위치를 선택하거나 기본 위치를 사용합니다.In the Location field, select a location for the storage account, or use the default location.

  8. 나머지 설정의 경우 다음을 구성합니다.For the rest of the settings, configure the following:

  9. 스토리지 계정 만들기 페이지의 프로젝트 세부 정보 섹션에서 구독리소스 그룹에 원하는 값을 선택합니다.In the Project details section of the Create storage account page, select the desired values for subscription and Resource group.

  10. 스토리지 계정 만들기 페이지의 인스턴스 세부 정보 섹션에서 스토리지 계정 이름을 입력한 다음 위치, 계정 종류복제 값을 선택합니다.In the Instance details section of the Create storage account page, enter the Storage account name then select values for Location, Account kind and Replication.

  11. 검토 + 만들기 를 선택 하 여 저장소 계정 설정을 검토 합니다.Select Review + create to review the storage account settings.

  12. 유효성을 검사 한 후 만들기 를 선택 합니다.Once validated, select Create.

Blob Storage 컨테이너 만들기Create Blob storage container

Blob 저장소 계정을 만든 후에는 해당 계정을 열고 다음을 수행 합니다.Once your Blob storage account is created, open it, then:

  1. Storage 탐색기 (미리 보기) 를 선택 합니다.Select Storage Explorer (Preview).

  2. 그런 다음 BLOB 컨테이너 를 마우스 오른쪽 단추로 클릭 합니다.Then right-click on BLOB CONTAINERS

  3. 드롭다운 목록에서 blob 컨테이너 만들기 를 선택 합니다.Select Create blob container from the drop-down list.

    Blob Storage 컨테이너 만들기

  4. 새 컨테이너 형식으로 이름을 입력 합니다.Enter a name in the New container form. 이 이름은 Blob storage 계정에 대 한 액세스를 제공 하기 위해 "blob 저장소-컨테이너-이름" 값에 사용 됩니다.You will use this name for the value of your "blob-storage-container-name" to provide access to your Blob storage account. 다음 지침에 유의 하세요.Note the following guidelines:

    • 이 이름에는 소문자, 숫자 및 하이픈만 사용할 수 있습니다.This name may only contain lowercase letters, numbers, and hyphens.
    • 이 이름은 문자 또는 숫자로 시작 해야 합니다.This name must begin with a letter or a number.
    • 각 하이픈 앞에는 하이픈을 사용할 수 없는 문자가와 야 합니다.Each hyphen must be preceded and followed by a valid non-hyphen character.
    • 이름은 3 ~ 007e; 63 자 사이 여야 합니다.The name must be between three and 63 characters long.

Blob storage 구성 정보 추가Add Blob storage configuration information

위에 표시 된 대로 봇 용 Blob storage를 구성 하는 데 필요한 Blob 저장소 키를 찾습니다.Find the Blob storage keys you need to configure Blob storage for your bot as shown above:

  1. Azure Portal에서 Blob storage 계정을 열고 설정 섹션에서 액세스 키 를 선택 합니다.In the Azure portal, open your Blob storage account and select Access keys in the Settings section.

    Blob 저장소 키 찾기

Blob 저장소 계정에 대 한 액세스를 제공 하려면 연결 문자열 을 "연결 문자열"의 값으로 사용 합니다.Use Connection string as the value for your "connection-string" to provide access to your Blob storage account.

구성 파일에 다음 정보를 추가합니다.Add the following information to your configuration file.

appsettings.jsonappsettings.json

"BlobConnectionString": "<your-blob-connection-string>",
"BlobContainerName": "<your-blob-container-name>",

Blob 저장소 패키지 설치Installing Blob storage packages

이전에 설치 하지 않은 경우 다음 패키지를 설치 합니다.If not previously installed, install the following packages.

Microsoft . n. i n.Install the Microsoft.Bot.Builder.Azure.Blobs NuGet package. NuGet 사용에 대 한 자세한 내용은 Nuget 패키지 관리자를 사용 하 여 Visual Studio에서 패키지 설치 및 관리를 참조 하세요.For more information on using NuGet, see Install and manage packages in Visual Studio using the NuGet Package Manager.

Blob storage 구현Blob storage implementation

Blob storage 는 bot 상태를 저장 하는 데 사용 됩니다.Blob storage is used to store bot state.

참고

버전 4.10부터 Microsoft.Bot.Builder.Azure.AzureBlobStorage 은 사용 되지 않습니다.As of version 4.10, Microsoft.Bot.Builder.Azure.AzureBlobStorage is deprecated. Microsoft.Bot.Builder.Azure.Blobs.BlobsStorage그 자리에 새를 사용 합니다.Use the new Microsoft.Bot.Builder.Azure.Blobs.BlobsStorage in its place.

다음 샘플 코드는 여기에 나열 된 예외와 함께 위에서 제공한 메모리 저장소 샘플과 동일한 봇 코드를 사용 하 여 실행 됩니다.The following sample code runs using the same bot code as the memory storage sample provided above, with the exceptions listed here.

아래 코드 조각에서는 로컬 메모리 저장소를 대체 하는 'Mystorage' 용 Blob 저장소의 구현을 보여 줍니다.The code snippets below show an implementation of Blob storage for 'myStorage' that replaces local Memory storage.

먼저 봇 빌더 Azure blob 라이브러리를 참조 하려면 시작 .cs 를 업데이트 해야 합니다.You first need to update Startup.cs to reference the bot builder Azure blobs library:

Startup.csStartup.cs

using Microsoft.Bot.Builder.Azure.Blobs;

그런 다음 ConfigureServices 시작 .cs 의 메서드에서 개체를 만들어 BlobsStorage 의 값을 전달 appsettings.json 합니다.Next, in the ConfigureServices method in Startup.cs, create the BlobsStorage object, passing in the values from appsettings.json. 이는 EchoBot 종속성 주입을 통해 생성자에 전달 됩니다.This will be passed into the EchoBot constructor through dependency injection.

//Use Azure Blob storage, instead of in-memory storage.
services.AddSingleton<IStorage>(
    new BlobsStorage(
        Configuration.GetValue<string>("dataConnectionString"),
        Configuration.GetValue<string>("containerName")
        ));

이제 봇 빌더 Azure blob 라이브러리를 참조 하도록 EchoBot 를 먼저 업데이트 해야 합니다.Now you first need to update EchoBot.cs to reference the bot builder Azure blobs library:

EchoBot.csEchoBot.cs

using Microsoft.Bot.Builder.Azure.Blobs;

다음으로 MemoryStorage 변수 ' private static readonly MemoryStorage _myStorage = new MemoryStorage (); '를 만드는 코드 줄을 제거 하거나 주석 처리 하 고 사용자 입력을 Blob Storage에 저장 하는 데 사용 되는 새 변수를 만듭니다.Next, remove or comment out the line of code that creates the MemoryStorage variable 'private static readonly MemoryStorage _myStorage = new MemoryStorage();', and create a new variable that will be used to save user input to the Blob Storage.

EchoBot.csEchoBot.cs

// variable used to save user input to CosmosDb Storage.
private readonly IStorage _myStorage;

그런 다음 개체를 IStorage 생성자에 전달 합니다 EchoBot .Then pass in the IStorage object to the EchoBot constructor:

public EchoBot(IStorage storage)
{
    if (storage is null) throw new ArgumentNullException();
    _myStorage = storage;
}

저장소에서 Blob Storage 계정을 가리키도록 설정한 후에는 이제 봇 코드가 Blob storage에서 데이터를 저장 하 고 검색 합니다.Once your storage is set to point to your Blob Storage account, your bot code will now store and retrieve data from Blob storage.

저장소에서 Blob Storage 계정을 가리키도록 설정한 후에는 이제 봇 코드가 Blob storage에서 데이터를 저장 하 고 검색 합니다.Once your storage is set to point to your Blob Storage account, your bot code will now store and retrieve data from Blob storage.

Blob storage bot 시작Start your Blob storage bot

봇을 로컬로 실행합니다.Run your bot locally.

에뮬레이터를 시작 하 고 Blob storage bot 연결Start the Emulator and connect your Blob storage bot

그런 다음 에뮬레이터를 시작 하 고 에뮬레이터에서 봇에 연결 합니다.Next, start the Emulator and then connect to your bot in the Emulator:

  1. 에뮬레이터 "시작" 탭에서 새 봇 구성 만들기 링크를 선택 합니다.Select the Create new bot configuration link in the Emulator "Welcome" tab.
  2. 봇을 시작할 때 표시되는 웹 페이지의 정보를 고려하여 필드를 채워 봇에 연결합니다.Fill in fields to connect to your bot, given the information on the webpage displayed when you started your bot.

Blob 저장소 봇과 상호 작용Interact with your Blob storage bot

봇에 메시지를 보내면 봇이 수신한 메시지를 나열합니다.Send a message to your bot, and the bot will list the messages it receives.

에뮬레이터 테스트 스토리지 봇

Blob storage 데이터 보기View your Blob storage data

봇을 실행하고 정보를 저장한 후 Azure Portal의 Storage Explorer 탭 아래에서 볼 수 있습니다.After you have run your bot and saved your information, we can view it in under the Storage Explorer tab in the Azure portal.

Blob 기록 스토리지Blob transcript storage

Azure Blob 기록 스토리지는 기록된 기록의 형태로 사용자 대화를 쉽게 저장하고 검색할 수 있는 특수 스토리지 옵션을 제공합니다.Azure blob transcript storage provides a specialized storage option that allows you to easily save and retrieve user conversations in the form of a recorded transcript. Azure Blob 음성 텍스트 스토리지는 봇의 성능을 디버깅할 때 검사할 사용자 입력을 자동으로 캡처하는 데 특히 유용합니다.Azure blob transcript storage is particularly useful for automatically capturing user inputs to examine while debugging your bot's performance.

참고

Python은 현재 Azure Blob 성적 증명서 저장소 를 지원 하지 않습니다.Python does not currently support Azure Blob transcript storage. JavaScript는 Blob 기록 저장소를 지원 하지만 다음 방향은 c #에만 해당 됩니다.While JavaScript supports Blob transcript storage, the following directions are for C# only.

Blob 성적 증명서 저장소 컨테이너 설정Set up a Blob transcript storage container

Azure Blob 기록 스토리지는 위의 섹션 "Blob Storage 계정 만들기" 및 "구성 정보 추가"에 설명된 단계를 따라 만들어진 동일한 Blob Storage 계정을 사용할 수 있습니다.Azure blob transcript storage can use the same blob storage account created following the steps detailed in sections "Create your blob storage account" and "Add configuration information" above. 이제 음성 텍스트를 저장할 컨테이너를 추가합니다.We now add a container to hold our transcripts

음성 텍스트 컨테이너 만들기

  1. Azure Blob Storage 계정을 엽니다.Open your Azure blob storage account.
  2. Storage 탐색기 를 선택 합니다.Select Storage Explorer.
  3. Blob 컨테이너 를 마우스 오른쪽 단추로 클릭하고 Blob 컨테이너 만들기 를 선택합니다.Right click on BLOB CONTAINERS and select create blob container.
  4. 성적 증명서 컨테이너의 이름을 입력 하 고 확인 을 선택 합니다.Enter a name for your transcript container and then select OK. ( Mybottranscripts 를 입력 했습니다.)(We entered mybottranscripts)

Blob 성적 기록 저장소 구현Blob transcript storage implementation

다음 코드는 기록 스토리지 포인터 _myTranscripts를 새 Azure Blob 기록 스토리지 계정에 연결합니다.The following code connects transcript storage pointer _myTranscripts to your new Azure blob transcript storage account. 새 컨테이너 이름으로이 링크를 만들려면에서 기록 <your-blob-transcript-container-name> 파일을 저장할 Blob 저장소 내에 새 컨테이너를 만듭니다.To create this link with a new container name, <your-blob-transcript-container-name>, creates a new container within Blob storage to hold your transcript files.

Blob 성적 증명서 저장소 는 bot 성적 증명서를 저장 하도록 설계 되었습니다.Blob transcript storage is designed to store bot transcripts.

참고

버전 4.10부터 Microsoft.Bot.Builder.Azure.AzureBlobTranscriptStore 은 사용 되지 않습니다.As of version 4.10, Microsoft.Bot.Builder.Azure.AzureBlobTranscriptStore is deprecated. Microsoft.Bot.Builder.Azure.Blobs.BlobsTranscriptStore그 자리에 새를 사용 합니다.Use the new Microsoft.Bot.Builder.Azure.Blobs.BlobsTranscriptStore in its place.

echoBot.csechoBot.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>");

   ...
}

Azure Blob 기록에 사용자 대화 저장Store user conversations in azure blob transcripts

Blob 컨테이너를 기록을 저장하는 데 사용할 수 있으면 봇과 사용자의 대화를 저장하도록 시작할 수 있습니다.After a blob container is available to store transcripts you can begin to preserve your users' conversations with your bot. 이러한 대화는 사용자가 봇과 상호 작용하는 방법을 확인하기 위해 나중에 디버깅 도구로 사용될 수 있습니다.These conversations can later be used as a debugging tool to see how users interact with your bot. 각 에뮬레이터 다시 시작 대화 는 새 기록 대화 목록 만들기를 시작 합니다.Each Emulator Restart conversation initiates the creation of a new transcript conversation list. 다음 코드는 사용자 대화 입력을 저장된 음성 텍스트 파일 내에 저장합니다.The following code preserves user conversation inputs within a stored transcript file.

  • 현재 음성 텍스트는 LogActivityAsync를 사용하여 저장됩니다.The current transcript is saved using LogActivityAsync.
  • 저장된 음성 텍스트는 ListTranscriptsAsync를 사용하여 검색됩니다.Saved transcripts are retrieved using ListTranscriptsAsync. 이 샘플 코드에서는 저장된 각 음성 텍스트의 ID가 "storedTranscripts"라는 목록에 저장됩니다.In this sample code the Id of each stored transcript is saved into a list named "storedTranscripts". 이 목록은 나중에 저장된 Blob 음성 텍스트 수를 관리하는 데 사용됩니다.This list is later used to manage the number of stored blob transcripts we retain.

echoBot.csechoBot.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);

    ...
}

저장된 Blob 음성 텍스트 관리Manage stored blob transcripts

저장된 음성 텍스트는 디버깅 도구로 사용할 수 있지만 시간이 지나면 저장된 음성 텍스트 수가 감당할 수 없을 정도로 커질 수 있습니다.While stored transcripts can be used as a debugging tool, over time the number of stored transcripts can grow larger than you care to preserve. 아래에 포함된 추가 코드는 DeleteTranscriptAsync를 사용하여 Blob 음성 텍스트 저장소에서 검색된 마지막 3개 음성 텍스트 항목을 제외한 모든 항목을 제거합니다.The additional code included below uses DeleteTranscriptAsync to remove all but the last three retrieved transcript items from your blob transcript store.

echoBot.csechoBot.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);
           }
       }
    }
    ...
}

클래스에 대 한 자세한 내용은 Azure Blob 성적 기록 저장소 를 참조 하세요.See Azure Blob Transcript Storage for more information about the class.

추가 정보Additional Information

Etag를 사용하여 동시성 관리Manage concurrency using eTags

봇 코드 예제에서는 각 IStoreItemeTag 속성을 *로 설정합니다.In our bot code example we set the eTag property of each IStoreItem to *. 저장소 개체의 eTag(엔터티 태그) 멤버는 Cosmos DB 내에서 동시성을 관리하는 데 사용됩니다.The eTag (entity tag) member of your store object is used within Cosmos DB to manage concurrency. eTag는 데이터베이스에 봇이 쓰고 있는 동일한 스토리지에서 다른 봇 인스턴스가 개체를 변경할 경우 수행할 작업을 지시합니다.The eTag tells your database what to do if another instance of the bot has changed the object in the same storage that your bot is writing to.

마지막 쓰기 우선 - 덮어쓰기 허용Last write wins - allow overwrites

별표(*)의 eTag 속성 값은 마지막 작성자가 우선임을 의미합니다.An eTag property value of asterisk (*) indicates that the last writer wins. 새 데이터 저장소를 만들 때 속성의 eTag*로 설정하여 이전에 저장하지 않은 데이터를 쓰고 있거나, 마지막 작성자가 모든 이전에 저장한 속성을 덮어쓰기를 원한다고 표시합니다.When creating a new data store, you can set eTag of a property to * to indicate that you have not previously saved the data that you are writing, or that you want the last writer to overwrite any previously saved property. 동시성은 봇에는 문제가 되지 않습니다. 쓰는 데이터에 대해 eTag 속성을 *로 설정하면 덮어쓰기를 활성화합니다.If concurrency is not an issue for your bot, setting the eTag property to * for any data that you are writing enables overwrites.

동시성을 유지 관리 및 덮어쓰기 방지Maintain concurrency and prevent overwrites

데이터를 Cosmos DB로 저장할 때 속성에 대한 동시 액세스를 방지하려면 eTag* 이외의 값을 사용하여 다른 봇 인스턴스의 변경 내용 덮어쓰기를 차단합니다.When storing your data into Cosmos DB, use a value other than * for the eTag if you want to prevent concurrent access to a property and avoid overwriting changes from another instance of the bot. 봇이 상태 데이터 저장을 시도하고 eTag가 스토리지의 eTag와 동일한 값이 아니면 etag conflict key= 메시지와 함께 오류 응답을 받습니다.The bot receives an error response with the message etag conflict key= when it attempts to save state data and the eTag is not the same value as the eTag in storage.

기본적으로 Cosmos DB 스토리지는 봇이 해당 항목에 쓸 때마다 스토리지 개체의 eTag 속성이 같은지 확인한 다음, 모든 쓰기 후에 새 고유 값으로 업데이트합니다.By default, the Cosmos DB store checks the eTag property of a storage object for equality every time a bot writes to that item, and then updates it to a new unique value after each write. 쓰기의 eTag 속성이 스토리지의 eTag와 일치하지 않은 경우 다른 봇 또는 스레드가 해당 데이터를 변경한 것입니다.If the eTag property on write doesn't match the eTag in storage, it means another bot or thread changed the data.

예를 들어, 봇이 저장된 메모를 편집했으나 이 봇이 다른 봇 인스턴스가 수행한 변경 내용을 덮어쓰는 것을 원치 않는다고 가정하겠습니다.For example, let's say you want your bot to edit a saved note, but you don't want your bot to overwrite changes that another instance of the bot has done. 다른 봇 인스턴스가 편집을 수행한 경우 사용자가 최신 업데이트로 버전을 편집하길 바랍니다.If another instance of the bot has made edits, you want the user to edit the version with the latest updates.

먼저 IStoreItem를 구현하는 클래스를 만듭니다.First, create a class that implements IStoreItem.

EchoBot.csEchoBot.cs

public class Note : IStoreItem
{
    public string Name { get; set; }
    public string Contents { get; set; }
    public string ETag { get; set; }
}

다음으로 스토리지 개체를 만들어 최초 메모를 만들고 이 개체를 스토리지에 추가합니다.Next, create an initial note by creating a storage object, and add the object to your store.

EchoBot.csEchoBot.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);

그런 다음, 나중에 메모를 액세스 및 업데이트하여 저장소에서 읽은 eTag를 유지합니다.Then, access and update the note later, keeping its eTag that you read from the store.

EchoBot.csEchoBot.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);
}

변경 내용을 기록하기 전에 저장소에서 메모가 업데이트된 경우 Write 호출에서 예외가 throw됩니다.If the note was updated in the store before you write your changes, the call to Write will throw an exception.

동시성을 유지하려면 항상 스토리지에서 속성을 읽은 다음, 읽은 속성을 수정하여 eTag를 유지 관리합니다.To maintain concurrency, always read a property from storage, then modify the property you read, so that the eTag is maintained. 저장소에서 사용자 데이터를 읽은 경우 응답에 eTag 속성이 포함됩니다.If you read user data from the store, the response will contain the eTag property. 데이터를 변경하고 업데이트된 데이터를 저장소에 쓴 경우 요청에 앞서 읽은 것과 동일한 값을 지정하는 eTag 속성이 포함됩니다.If you change the data and write updated data to the store, your request should include the eTag property that specifies the same value as you read earlier. 그러나 eTag*로 설정된 개체를 쓰면 이 쓰기가 다른 변경 내용을 덮어쓰게 됩니다.However, writing an object with its eTag set to * will allow the write to overwrite any other changes.

다음 단계Next steps

이제 스토리지에서 직접 읽고 쓰는 방법을 알았으므로 상태 관리자를 사용하여 이를 수행하는 방법을 살펴보겠습니다.Now that you know how to read read and write directly from storage, lets take a look at how you can use the state manager to do that for you.