C# DirectLine REST API 流程离开后如何续接原有机器人会话
Direct Line 会话续接问题解决方案
核心结论
- 不需要强制新建
DirectLineClient实例,复用缓存的实例性能更好,但无状态API场景下新建实例也可以正常续接会话 - 你当前连接失败是两个代码逻辑错误导致的:重复创建会话、旧Streaming连接未释放触发服务端单活限制
问题根因说明
- 重复创建会话:你调用
GenerateTokenForNewConversationAsync时,服务端已经生成了绑定有效token的正式会话,后续你又调用StartConversationAsync会再生成一个全新的独立会话。你发消息时用的是第二个会话的ID,但后续续接时如果用第一次生成的token和会话ID,自然会匹配失败。 - Streaming连接单活限制:Direct Line的流式连接机制要求,同一个会话ID同一时间只允许存在一个活跃连接。如果上一次请求结束后没有主动断开旧连接,服务端会在检测到旧连接失效前(最长30秒超时)拒绝所有新的连接请求,直接返回连接错误。
正确实现逻辑
首次创建会话流程
修正冗余的会话创建逻辑,只保留一次会话生成操作:
- 用全局Direct Line密钥生成会话token和ID,将这两个值和过期时间持久化存储(可选用数据库、分布式缓存,和外部应用的用户/业务会话标识做映射),后续续接必须依赖这两个存储值:
var tokenClient = new DirectLineClient( new Uri(Endpoint), new DirectLineClientCredentials(Secret)); // 该接口调用完成后,已经生成可用的正式会话,无需再调用StartConversationAsync var conversation = await tokenClient.Tokens.GenerateTokenForNewConversationAsync(); // 持久化存储字段:conversation.Id(会话ID)、conversation.Token(会话令牌)、conversation.ExpiresIn(过期时间) - 用拿到的会话token初始化客户端,直接传入已生成的会话ID建立流式连接,不需要重复调用
StartConversationAsync:var client = new DirectLineClient( new Uri(Endpoint), new DirectLineClientCredentials(conversation.Token)); // 直接绑定已生成的会话ID建立连接 await client.StreamingConversations.ConnectAsync( conversation.Id, ReceiveActivities); - 发送消息时直接使用已有的会话ID即可:
var response = await client.StreamingConversations.PostActivityAsync( conversation.Id, new Activity() { Type = "message", Text = message, From = from }); - 请求处理完成准备释放资源前,主动调用客户端释放方法断开连接,避免服务端等待超时占用连接配额:
// 主动断开连接,服务端会立刻释放该会话的连接占用,后续可以立刻新建连接 await client.DisposeAsync();
跨请求续接同一会话流程
当外部应用再次发起请求需要续接之前的会话时,按以下步骤操作:
- 根据外部应用传入的业务标识,从持久化存储中取出对应会话的
ConversationId、Token,先校验token剩余有效期,如果不足10分钟可调用刷新接口续期,更新存储的token和过期时间。 - 用存储的token初始化新的
DirectLineClient实例,直接调用ConnectAsync传入存储的会话ID,重新绑定消息接收回调即可正常收发消息,不需要重新生成token或创建新会话。
性能优化建议
如果API服务和Direct Line服务之间网络延迟较高,可以把初始化好的DirectLineClient实例、对应会话ID、最后活跃时间存在内存缓存中,设置5-10分钟的滑动过期时间:
- 同一个会话的后续请求直接复用缓存中的客户端实例,不需要重复建立Streaming连接
- 滑动过期时间到期后再主动释放客户端实例断开连接,能大幅降低接口响应延迟
- 注意控制缓存的客户端总数量,避免占用过多内存
注意:绝对不要对已存在的会话调用
StartConversationAsync,该接口仅用于创建全新会话,调用后会生成新的会话ID,和原有会话完全独立。
内容的提问来源于stack exchange,提问作者Excali 2
相关产品推荐
相关产品推荐

