c# - IIS 池回收后的 session 引用(并发字典变为空白)

标签 c# iis botframework microsoft-teams azure-blob-storage

我们使用 .Net c# sdk 在 Bot Framework-4 中设计了一个机器人。该机器人托管在 IIS 上并且可用 在不同的 channel 上,例如 Directline、MS Teams 等。我们希望向 MS 团队中的所有用户发送主动消息,以通知他们,无论他们是否与机器人进行通信。主动消息将是 1:1 消息。

经过大量研发后,我们发现只有在存在对话引用时,我们才能向用户发送主动消息。 (让我知道是否还有其他方法。)

使用下面的链接和示例向用户发送主动消息:

Proactive Message Sample

Document Referred

我们正在使用 cosmos DB 容器和自动保存中间件来进行机器人对话状态和用户状态管理。

Startup.cs文件的ConfigureServices方法中的代码:

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 池被回收时,具有 session 引用的并发字典会变成空白,并且我们无法将主动消息发送给用户,如何将其存储在 Blob 存储中并在 Notify Controller 中访问它?

  2. 我们希望向所有用户发送主动消息,无论他们是否与机器人通信,有什么方法可以实现这一点?尝试了 this 中的第三种方法文章。但挑战是,我们无法根据用户 ID 或用户主体名称向用户发送消息。

最佳答案

  1. 有多种方法可以存储对话和用户信息。您应该将这些详细信息存储在更持久的位置而不是内存中。这是sample app code它在安装应用程序时将用户详细信息以及对话 ID 存储在 cosmos DB 中。你可以看看实现部分。它可以是任何存储(blob、SQL)。
  2. 要发送主动消息,用户必须有权访问您的应用。您可以为租户中的每个人安装您的应用程序 Teams admin portal 。这是reference documentation用于从管理门户管理应用程序。

您需要拥有(机器人和用户之间的)对话 ID 才能发送主动消息。当为用户或用户所属的团队/组安装机器人时,会创建对话 ID。

关于c# - IIS 池回收后的 session 引用(并发字典变为空白),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63261004/

相关文章:

c# - 在维护 session 的同时将网络场迁移到 asp.net 的运行时版本 4

node.js - userId是全局唯一标识符吗?

C# 从 powershell 脚本获取变量

c# - Orchard 。如何渲染 'HeadScripts' 形状之前的东西?

c# - 如何获取 null 而不是 KeyNotFoundException 按键访问字典值?

Azure BotFramework-WebChat javascript 初始化 DirectLine 时出错

azure - 请验证 QnAMaker 服务中的 Azure 搜索资源是否已启动并正在运行

c# - 尚未注册该类型的服务

html - IE8 和选择菜单上的边框 css 属性

iis - 更新配置文件中的 IIS 绑定(bind),而不是 GUI