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

Docker化Rasa与非Docker化React前端多用户会话隔离问题求助

解决Rasa与React前端会话隔离失效问题

看起来你已经做了不少配置,但核心问题应该是没有把用户的唯一标识(MongoDB的user._id)正确绑定到Rasa的会话跟踪器(tracker)的sender_id上。自动生成的sessionId可能会因为页面刷新、SocketIO重连等情况被复用或重置,导致会话混淆。下面是一步步的修复方案:


1. 调整自定义SocketIO连接器,强制用用户ID作为Rasa的sender_id

Rasa的会话隔离完全依赖于sender_id,所以必须把前端传来的MongoDB user._id作为sender_id传递给Rasa,而不是自动生成的临时sessionId。

在你的自定义连接器代码中,修改消息处理逻辑:

// 自定义SocketIO连接器的消息接收部分
socket.on('user_uttered', async (message) => {
  // 从customData中提取用户的MongoDB _id
  const userUniqueId = message.customData?.user_id;
  
  if (!userUniqueId) {
    console.error('缺少用户唯一ID,无法实现会话隔离');
    return;
  }

  // 向Rasa发送请求时,指定sender为用户唯一ID
  await fetch('http://your-rasa-service:5005/webhooks/socketio/webhook', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      sender: userUniqueId, // 关键:用用户唯一ID作为sender_id
      message: message.text,
      customData: message.customData
    })
  });
});

2. 验证Rasa端的会话配置

确保Rasa的配置没有缓存会话,并且正确识别sender_id:

  • 在credentials.yml中,确认SocketIO连接器的配置:
    socketio:
      user_message_evt: user_uttered
      bot_message_evt: bot_uttered
      session_persistence: false
      custom_connector: "path.to.your.CustomSocketIOConnector"
    
  • 在自定义动作中,打印sender_id确认是否为用户的MongoDB user._id:
    from rasa_sdk import Action, Tracker
    from rasa_sdk.executor import CollectingDispatcher
    
    class ActionCheckSenderId(Action):
        def name(self) -> str:
            return "action_check_sender_id"
    
        def run(self, dispatcher: CollectingDispatcher,
                tracker: Tracker,
                domain: dict) -> list:
            # 打印当前会话的sender_id,确认是用户的唯一ID
            print(f"当前会话sender_id: {tracker.sender_id}")
            return []
    

3. 修复Botfront Webchat的初始化逻辑

确保Webchat组件每次都用用户的唯一ID初始化,并且清理旧会话:

import { Widget } from 'botfront-webchat';
import { useEffect } from 'react';

function ChatWidget({ currentUser }) {
  useEffect(() => {
    if (currentUser) {
      // 先销毁可能存在的旧会话
      Widget.destroy();
      // 用用户的MongoDB _id作为userId和customData
      Widget.init({
        socketUrl: 'http://your-rasa-socketio-url',
        storage: 'session',
        userId: currentUser._id, // 绑定用户唯一ID
        customData: { user_id: currentUser._id },
        session_persistence: false,
        resetOnClose: true // 关闭聊天窗口时重置会话
      });
    }

    return () => Widget.destroy();
  }, [currentUser]);

  return <div id="webchat" />;
}

4. 排查SocketIO连接复用问题

Docker化的Rasa可能存在SocketIO连接复用的情况,需要在连接器中给每个用户绑定独立的Socket房间:

// 自定义连接器的连接处理逻辑
socket.on('connect', () => {
  const userUniqueId = socket.handshake.query.customData?.user_id;
  if (userUniqueId) {
    // 让用户加入以自己ID命名的房间
    socket.join(userUniqueId);
  }
});

// 发送Bot消息时,只发送到用户自己的房间
function sendBotMessage(senderId, message) {
  io.to(senderId).emit('bot_uttered', message);
}

核心逻辑总结:会话隔离的本质是让Rasa用用户的唯一标识(而非临时sessionId)来区分不同会话。只要从Webchat、连接器到Rasa端全程传递MongoDB的user._id作为sender_id,再配合关闭会话持久化的配置,就能解决刷新页面看到历史消息的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:02:38