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

多域名/端口数据同步方案咨询 基于socket.io的跨域聊天实时同步问题

跨域名Socket.io实时聊天方案实现

核心逻辑

Socket.io原生支持跨域通信,你需要解决的核心问题是会话身份绑定、跨域合法性校验、消息定向路由,而非单纯的网络连通问题。

具体实现步骤

1. 服务端Socket.io开启跨域配置

Node端的Socket.io服务优先完成跨域规则配置,支持动态校验域名合法性,生产环境不要直接使用通配符:

const { Server } = require("socket.io");
const io = new Server(3000, {
  cors: {
    // 动态校验域名,需支持任意域名接入时可直接放行,后续在业务层做签名校验
    origin: (origin, callback) => callback(null, true),
    credentials: true
  },
  // 默认开启,WebSocket连接失败自动降级为HTTP长轮询,适配严格跨域限制的浏览器环境
  transports: ["websocket", "polling"]
});

2. 嵌入端(第三方域名聊天组件)会话初始化

每个嵌入到第三方站点的聊天组件初始化时,生成唯一访客标识,和分配给接入站点的唯一appKey绑定,上报到服务端完成会话关联:

import { io } from "socket.io-client";
// 访客ID存在本地存储,支持页面刷新后续会
const visitorId = localStorage.getItem('chat_visitor_id') || Math.random().toString(36).slice(2, 12);
localStorage.setItem('chat_visitor_id', visitorId);

const socket = io("你的主域名Socket服务地址", {
  query: {
    appKey: "提前分配给接入站点的唯一标识",
    userType: "visitor",
    visitorId: visitorId
  },
  withCredentials: true
});

// 访客发送消息事件
const sendMsg = (content) => {
  socket.emit("visitor_send_msg", { content, timestamp: Date.now() });
};

// 监听坐席回复消息
socket.on("receive_agent_msg", (data) => {
  console.log("收到坐席消息:", data.content);
});

3. 服务端会话绑定与消息路由

服务端维护会话映射关系,同时用房间机制对坐席做分组,实现消息定向推送:

// 生产环境用Redis存储,支持多实例部署、分布式会话共享
const sessionMap = new Map();

io.on("connection", (socket) => {
  const { appKey, visitorId, userType, agentId } = socket.handshake.query;
  
  // 访客接入逻辑
  if (userType === "visitor") {
    const sessionId = `${appKey}_${visitorId}`;
    // 绑定会话ID与Socket实例ID
    sessionMap.set(sessionId, socket.id);
    // 通知对应商户的所有坐席有新访客接入
    io.to(`merchant_${appKey}_agent_room`).emit("new_visitor", { sessionId, visitorId });

    // 转发访客消息到对应坐席房间
    socket.on("visitor_send_msg", (data) => {
      io.to(`merchant_${appKey}_agent_room`).emit("receive_visitor_msg", {
        sessionId,
        content: data.content,
        timestamp: data.timestamp
      });
    });
  }

  // 坐席接入逻辑
  if (userType === "agent") {
    // 坐席加入所属商户的专属房间,接收该商户下所有访客消息
    socket.join(`merchant_${appKey}_agent_room`);

    // 转发坐席回复到对应访客窗口
    socket.on("agent_send_msg", (data) => {
      const targetSocketId = sessionMap.get(data.sessionId);
      if (targetSocketId) {
        io.to(targetSocketId).emit("receive_agent_msg", {
          content: data.content,
          timestamp: data.timestamp
        });
      }
    });
  }
});

4. 主域名坐席端接入

坐席登录后携带身份标识接入Socket服务,加入对应商户房间即可接收消息:

import { io } from "socket.io-client";
const socket = io("你的主域名Socket服务地址", {
  query: {
    userType: "agent",
    appKey: "当前坐席所属商户的appKey",
    agentId: "坐席账号唯一ID"
  }
});

// 监听新访客接入
socket.on("new_visitor", (data) => {
  console.log("新访客接入:", data.sessionId);
});

// 监听访客发送的消息
socket.on("receive_visitor_msg", (data) => {
  console.log("收到访客消息:", data.content);
});

// 坐席发送回复
const sendReply = (sessionId, content) => {
  socket.emit("agent_send_msg", { sessionId, content, timestamp: Date.now() });
};

生产环境优化建议

  • 会话映射、房间关系改用Redis存储,支持Socket服务多实例扩容,避免单点故障
  • 所有消息先写入数据库再推送,防止消息丢失,支持历史消息回溯
  • 增加接入签名校验,嵌入端初始化时携带appKey+时间戳+签名,服务端校验合法性,拦截恶意接入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:39:01