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

页面刷新时Socket.io函数重复执行两次问题求助

解决Socket.io页面刷新时重复创建房间的问题

一、先排查客户端重复触发的根源

  1. 检查Socket实例是否重复创建
    你的客户端代码里缺少Socket实例初始化代码(const socket = io()),如果这段代码被执行两次(比如脚本被重复引入、Handlebars模板渲染时重复加载了script标签),会建立两个Socket连接,每个连接都会触发一次create_room事件。

    • 确认页面里的Socket.io脚本只引入一次:检查Handlebars模板中是否重复添加了<script src="/socket.io/socket.io.js"></script>,或是在多个模板文件里都引入了这段脚本。
    • 确保Socket实例只初始化一次:把const socket = io()放在全局或模块级作用域,避免在DOMContentLoaded回调里重复创建。
  2. 防止create_room重复触发
    给客户端加一个执行标志,确保页面加载时只触发一次事件:

    let isRoomCreated = false;
    const handlereateRoom = () => {
        if (isRoomCreated) return;
        isRoomCreated = true;
        socket.emit('create_room', {
            roomId: roomName,
            author: user._id,
            invitedUsers: ['numero1', 'numero2']
        });
    }
    
  3. 验证DOMContentLoaded是否重复触发
    在回调里加日志,确认是否执行两次:

    document.addEventListener('DOMContentLoaded', async () => {
        console.log('DOM加载完成'); // 刷新页面看控制台是否输出两次
        // 原有代码...
    });
    

    如果输出两次,说明脚本被重复执行,排查Handlebars模板的渲染逻辑,比如是否在布局模板和页面模板里都引入了这段脚本。

二、服务端添加幂等性校验(核心防御)

即使客户端不小心重复发送请求,服务端也要保证不会重复创建房间:

const createASingleRoom = socket => {
    socket.on('create_room', async data => {
        // 先根据用户+房间名查询是否已存在该房间
        const existingRoom = await Room.findOne({
            author: data.author,
            roomName: data.roomId // 建议把客户端传的roomId改名为roomName,避免和服务端生成的UUID混淆
        });
        
        if (existingRoom) {
            console.log('房间已存在', existingRoom);
            socket.emit('room_created', existingRoom); // 返回已存在的房间
            return;
        }
        
        // 不存在则创建新房间
        const roomObject = {
            roomId: uuidv4(),
            author: data.author,
            roomName: data.roomId,
            invitedUsers: data.invitedUsers || []
        };
        
        console.log('创建新房间', roomObject);
        const newRoom = await Room.create(roomObject);
        socket.emit('room_created', newRoom);
    })
}

通过业务唯一标识(用户ID+房间名)做前置检查,彻底避免重复创建。

三、额外排查点

  • 检查服务端的io.on('connection')是否被多次绑定:确认是否在多个文件里都调用了该监听,导致每个新连接重复绑定create_room事件。
  • 确认浏览器刷新行为:部分场景下刷新会触发两次请求,但通过客户端标志位和服务端校验可覆盖这种情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 10:42:52