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

Microsoft Bot Framework多用户WebSocket会话创建及变量覆盖问题排查

解决Microsoft Bot Framework多用户会话变量覆盖问题

你的问题核心是全局变量被多用户共享覆盖,比如代码里的ws、adapter、connectionToken等都是全局作用域,当多个用户触发CCP命令时,这些变量会被新用户的连接信息覆盖,导致老用户的会话出错。要实现每个用户的独立会话,需要把用户专属的会话数据和资源隔离存储,以下是具体方案:

1. 核心思路:用用户ID作为标识隔离会话资源

创建一个全局的会话存储对象,以每个用户的唯一ID(turnContext.activity.from.id)为键,存储该用户专属的WebSocket实例、连接令牌、适配器等数据,确保每个用户的资源互不干扰。

2. 修改后的代码示例

// 全局会话存储,每个用户ID对应自己的会话数据
const userSessions = {};

// 原CCP命令处理逻辑修改
if (turnContext.activity.text === 'CCP') {
    const userId = turnContext.activity.from.id;
    const url = await this.connectToAgent(members);
    const initialMessage = {
        topic: "aws/subscribe",
        content: {
            topics: ["aws/chat"]
        }
    };

    // 为当前用户创建专属WebSocket实例,存入会话存储
    const ws = new WebSocket(url[1]);
    userSessions[userId] = {
        ws: ws,
        adapter: turnContext.adapter,
        conversationReference: TurnContext.getConversationReference(turnContext.activity),
        connectionToken: connectionToken, // 确保这个token是当前用户的专属值
        sendHistory: sendHistory // 同理,sendHistory也要是用户专属的
    };

    ws.addEventListener("open", () => {
        ws.send(JSON.stringify(initialMessage));
    });

    await turnContext.sendActivity("Please wait while we connect you to an agent.");

    // 监听当前用户WebSocket消息,处理时关联自己的会话数据
    ws.addEventListener('message', async function (event) {
        const msg = JSON.parse(event.data);
        // 处理消息时从userSessions[userId]获取当前用户的会话资源
        const session = userSessions[userId];
        // 后续逻辑使用session.adapter、session.conversationReference等,避免全局变量
    });

    // 发送聊天历史的逻辑也改为使用当前用户的会话数据
    let sendChatHistory = (function(userId) {
        let executed = false;
        return function() {
            if (!executed) {
                executed = true;
                const session = userSessions[userId];
                const param = {
                    ConnectionToken: session.connectionToken, /* 使用用户专属token */
                    Content: session.sendHistory, /* 使用用户专属历史 */
                    ContentType: 'text/plain', /* required */
                };
                connectparticipant.sendMessage(param,async function (err, data) {
                    // 清空用户专属的历史数据
                    session.sendHistory = '';
                    if (err) {
                        // 错误消息发送给当前用户
                        await session.adapter.continueConversation(session.conversationReference, async (ctx) => {
                            await ctx.sendActivity("Error while sending a message");
                        });
                    }
                });
            }
        };
    })(userId);
    
    sendChatHistory();   
}

3. 额外优化建议

  • 会话清理:当用户断开连接或会话结束时,记得从userSessions中移除对应条目,并关闭WebSocket连接,避免资源泄漏。
  • 使用内置状态管理:如果你的机器人已配置UserState或ConversationState,可以将用户会话数据存入官方状态存储,比自定义的userSessions更可靠,尤其适合多实例部署场景(需配合分布式存储如Azure Cosmos DB)。

内容的提问来源于stack exchange,提问作者Mohammed Tariq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:18:27