You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用BotFramework向MS Teams千余用户发消息超时失败求助

MS Teams机器人批量发送消息超时问题解决方案

问题背景

我正在开发一款MS Teams机器人,使用Microsoft.Bot.Builder(4.15.2)、**Microsoft.Bot.Connector(4.15.2)**异步向1000名用户发送消息,C#核心代码如下:

public async Task SendMessage(string tenantId, ConnectorClient connectorClient, UserDetails user, Activity personalMessageActivity)
{
    ChannelAccount member = GetChannelAccount(user.id, user.name);
    ConversationParameters conversationParameters = GetConversationParameters(tenantId, member);
    string conversationId = user.conversationId;
    var resp = await connectorClient.Conversations.SendToConversationAsync(user.conversationId, personalMessageActivity);
}

public async Task SendMessageToUsers(ProactiveMessage proactiveMessage, string tenantId, ConnectorClient connectorClient, UserDetails member, Activity personalMessageActivity)
{
   var result = await SendMessage(tenantId, connectorClient, member, personalMessageActivity);          
}

通过以下代码批量执行:

List<Task> TaskList = new List<Task>();
foreach (UserDetails member in allMembersArr)
{
    TaskList.Add(SendMessageToUsers (proactiveMessage, tenantId, connectorClient, member, personalMessageActivity));                        
}
await Task.WhenAll(TaskList);

执行后仅约600名用户成功收到消息,其余用户出现错误:连接尝试失败,因为连接方未在一段时间后正确响应,或已建立的连接失败,因为连接主机未能响应。尝试多线程与异步编程仍未解决。

后续改用Node.js(botbuilder@4.15.0、botframework-connector@4.15.0),核心代码如下:

const sendMessage = (membersArry, activity) => {
  membersArry.forEach((member) => {
    connectorClient.conversations.sendToConversation(
      member.conversationId,
      activity
    );
  });
}

// 依赖版本
"botbuilder": "^4.15.0",
"botframework-connector": "^4.15.0",

问题依然存在:每次运行都会随机出现用户超时错误Error: connect ETIMEDOUT 52.xx.xxx.x:443,无法向全部1000名用户发送消息。

注:使用的Azure Bot定价层为Standard S1。

解决方案建议

1. 控制并发请求数

直接发起1000个并发请求会触发服务端限流或超出本地TCP连接池限制,建议分批并发执行,控制每批次请求数量(推荐20-50个),批次间可添加短暂延迟。

C# 分批示例:

int batchSize = 30;
for (int i = 0; i < allMembersArr.Count; i += batchSize)
{
    var currentBatch = allMembersArr.Skip(i).Take(batchSize);
    var batchTasks = currentBatch.Select(member => 
        SendMessageToUsers(proactiveMessage, tenantId, connectorClient, member, personalMessageActivity)
    );
    await Task.WhenAll(batchTasks);
    // 批次间延迟1秒,避免服务端压力过载
    await Task.Delay(1000);
}

Node.js 分批示例:

const sendMessageInBatches = async (membersArray, activity, batchSize = 30) => {
    for (let i = 0; i < membersArray.length; i += batchSize) {
        const batch = membersArray.slice(i, i + batchSize);
        // 等待当前批次所有请求完成
        await Promise.all(batch.map(member => 
            connectorClient.conversations.sendToConversation(member.conversationId, activity)
        ));
        // 批次间添加延迟
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
};

2. 添加重试机制

针对超时、临时网络波动等异常,添加指数退避重试策略,提升消息送达率。

C# 使用Polly库实现重试:

// 先安装Polly包:Install-Package Polly
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .Or<TaskCanceledException>() // 捕获超时类异常
    .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

// 在SendMessage方法中使用重试
await retryPolicy.ExecuteAsync(() => 
    connectorClient.Conversations.SendToConversationAsync(user.conversationId, personalMessageActivity)
);

Node.js 使用p-retry库实现重试:

// 先安装p-retry包:npm install p-retry
const pRetry = require('p-retry');

const sendWithRetry = async (member, activity) => {
    await pRetry(() => 
        connectorClient.conversations.sendToConversation(member.conversationId, activity),
        { 
            retries: 3, 
            factor: 2, // 指数退避因子
            onFailedAttempt: (error) => {
                console.log(`发送给用户${member.id}失败,重试次数: ${error.attemptNumber}`);
            }
        }
    );
};

3. 优化ConnectorClient实例管理

避免复用单个ConnectorClient处理大量请求,可针对每个批次创建新的实例,或者调整客户端的连接池配置(比如增大最大连接数)。

C# 示例:

// 每个批次创建新的ConnectorClient实例
var credentials = new MicrosoftAppCredentials(appId, appPassword);
var connectorClient = new ConnectorClient(new Uri(serviceUrl), credentials);

4. 检查Azure Bot服务限制

Standard S1层存在请求速率限制,可登录Azure门户查看Bot服务的监控指标(请求数、错误率、限流次数),确认是否触发了平台限流。若限流频繁,可考虑升级定价层或调整发送节奏。

内容的提问来源于stack exchange,提问作者Sandesh Sawant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:31:30