如何绕过Teams Bot的15秒HTTP响应超时限制?
解决Teams Bot 15秒响应限制的方案
Teams平台强制要求Bot在15秒内返回HTTP 200状态码,直接等待长耗时API响应必然触发超时取消异常。正确的处理思路是采用异步处理+主动推送结果的模式,具体实现如下:
1. 核心思路:先确认接收,再后台处理
收到用户请求后,第一时间返回空响应或临时提示满足平台的15秒要求,随后在后台异步执行API调用,完成后主动给用户推送结果。
修改后的示例代码
public async Task<ICommandResponse> HandleCommandAsync(ITurnContext turnContext, CommandMessage message, CancellationToken cancellationToken = default) { // 1. 立即发送临时提示,同时返回空响应,确保15秒内完成请求响应 await turnContext.SendActivityAsync("正在处理你的请求,请稍候...", cancellationToken: cancellationToken); // 2. 启动后台异步任务处理API调用,不阻塞当前响应流程 _ = Task.Run(async () => { try { // 复用单例HttpClient(建议通过依赖注入获取,避免频繁创建导致Socket耗尽) var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Post, "https://RESTENDPOINT/"); var dataText = message.Text; Message msg = new Message() { role = "user", content = message.Text }; ChatParams chatParams = new ChatParams() { model = "gpt-4-1106-preview", temperature = 0.3f, messages = new List<Message>() { msg }, stream = false }; RequestBody requestBodyObject = new RequestBody() { chat_params = chatParams, conversation_id = 1, assistant_id = 1, uuid = Guid.NewGuid().ToString() }; var requestBody = JsonConvert.SerializeObject(requestBodyObject); var content = new StringContent(requestBody, null, "application/json"); request.Content = content; var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); string responseText = await response.Content.ReadAsStringAsync(); ChatCompletion chatCompletion = JsonConvert.DeserializeObject<ChatCompletion>(responseText); var responseContent = chatCompletion.choices[0]?.message.content; _logger.LogInformation(responseContent); // 3. API处理完成后,主动向用户推送结果 await turnContext.SendActivityAsync(responseContent, cancellationToken: cancellationToken); } catch (Exception ex) { _logger.LogError(ex, "API调用失败"); await turnContext.SendActivityAsync("处理请求时出错,请稍后重试", cancellationToken: cancellationToken); } }, cancellationToken); // 返回空响应,满足平台15秒内返回200的要求 return new TextCommandResponse(""); }
2. 关键注意事项
- HttpClient复用:禁止每次请求创建新的
HttpClient,建议通过依赖注入注入单例实例,避免Socket资源耗尽。 - 会话上下文安全处理:如果后台任务耗时极长,建议保存
ConversationReference而非直接持有原turnContext,后续通过Adapter.ContinueConversationAsync恢复上下文发送消息,示例代码如下:// 初始方法中保存会话引用 var conversationReference = turnContext.Activity.GetConversationReference(); // 后台任务中恢复上下文发送消息 await _adapter.ContinueConversationAsync(_appId, conversationReference, async (context, ct) => { await context.SendActivityAsync(responseContent, cancellationToken: ct); }, cancellationToken); - 异常捕获:后台任务必须捕获所有异常,向用户推送错误提示,避免静默失败。
- 取消令牌传递:确保后台任务正确处理
cancellationToken,在用户取消请求时及时终止操作,避免资源浪费。
内容的提问来源于stack exchange,提问作者erase.ego
相关产品推荐
相关产品推荐

