ссылка на диалог (параллельный словарь становится пустым) после перезапуска пула IIS - PullRequest
2 голосов
/ 05 августа 2020

У нас есть дизайн бота в Bot framework-4 с использованием. Net c# sdk. Этот бот размещен в IIS и доступен по разным каналам, таким как Directline, MS Teams и c. Мы хотим отправлять проактивные сообщения всем пользователям в командах MS, чтобы уведомить их, независимо от того, общались они с ботом или нет. Проактивные сообщения будут иметь формат 1: 1.

Проведя много исследований и разработок, мы обнаружили, что сможем отправлять проактивные сообщения пользователю только при наличии ссылки на диалог. (дайте мне знать, если возможен и другой способ.)

Использование приведенной ниже ссылки и образца для отправки упреждающего сообщения пользователю:

Образец упреждающего сообщения

Ссылка на документ

Мы используем контейнер cosmos DB и промежуточное ПО с автоматическим сохранением для состояния беседы бота и управления состоянием пользователя.

Код в методе ConfigureServices файла Startup.cs:

var blobDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Blob service in your .bot file.");
var BlobDb = blobDbService as BlobStorageService;

var dataStore = new AzureBlobStorage(BlobDb.ConnectionString, BlobDb.Container);
var userState = new UserState(dataStore);
var conversationState = new ConversationState(dataStore);
            
services.AddSingleton(dataStore);
services.AddSingleton(userState);
services.AddSingleton(conversationState);
services.AddSingleton<ConcurrentDictionary<string, ConversationReference>>();
services.AddSingleton(new BotStateSet(userState, conversationState));
services.AddBot<EnterpriseTiBOT>(options =>
{
  // Autosave State Middleware (saves bot state after each turn)
    options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));
}

Код для хранения справочника разговоров для каждого пользователя:

private void AddConversationReference(Activity activity)
        {
           
            var conversationReference = activity.GetConversationReference();
            _conversationReferences.AddOrUpdate(conversationReference.User.Id, conversationReference, (key, newValue) => conversationReference);
        }
protected override async Task OnStartAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
        {
            AddConversationReference(dc.Context, cancellationToken);
        }

Код в notifyContoller такой же, как код из GitHub Sample. Мы сталкиваемся с двумя проблемами:

  1. Параллельный словарь, имеющий ссылку на диалог, становится пустым, когда пул IIS повторно используется, и мы не можем отправить проактивное сообщение пользователю, как сохранить его в хранилище BLOB-объектов и получить к нему доступ в контроллере уведомлений?

  2. Мы хотим отправить упреждающее сообщение всем пользователям, независимо от того, общались ли они с ботом или нет, каким-либо способом добиться этого? Пробовал 3-й подход из этой статьи. Но проблема в том, что мы не можем отправить сообщение пользователю на основе идентификатора пользователя или основного имени пользователя.

1 Ответ

2 голосов
/ 05 августа 2020
  1. Есть несколько способов сохранить беседу и информацию о пользователе. Эти детали следует хранить в более надежном месте, а не в памяти. Вот пример кода приложения , в котором хранятся сведения о пользователе и идентификатор разговора в cosmos DB во время установки приложения. Вы можете изучить часть реализации. Это может быть любое хранилище (blob, SQL).
  2. Для отправки упреждающего сообщения Пользователь должен иметь доступ к вашему приложению. Вы можете установить свое приложение для всех в клиенте с портала администрирования Teams . Вот справочная документация для управления приложением с портала администратора.

Вам нужен идентификатор разговора (между ботом и пользователем) для отправки упреждающего сообщения. И идентификатор разговора создается, когда бот устанавливается для пользователя или в команде / группе, частью которой является пользователь.

...