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

Node.js中Kahoot Bot同名重复报错:Socket清理后仍无效求助

解决Kahoot机器人「Duplicate name」重复名称错误

问题根源分析

  1. 服务器端缓存机制:Kahoot服务器会对已登录的玩家名称做短期会话缓存,即便客户端主动断开连接,服务器不会立刻释放该名称,需要等待会话超时(通常几秒到十几秒)。
  2. 现有清理逻辑的缺陷:
    • 代码中定义的是单个bot变量,但进程退出监听里循环的是未定义的bots,导致清理逻辑根本没执行。
    • bot.leave()是异步操作,你直接同步执行后续的socket关闭、监听器移除,可能leave()还没完成就切断了连接,服务器没收到注销请求,自然不会释放名称。

修正后的代码

const Kahoot = require("kahoot.js-latest");
const colors = require('colors');

const bot = new Kahoot();

async function cleanup() {
    try {
        // 先等待leave执行完成,确保服务器收到注销请求
        await bot.leave();
    } catch (err) {
        console.log("Leave failed:".red, err);
    }
    // 移除所有监听器
    bot.removeAllListeners();
    // 安全关闭socket连接
    if (bot.socket) {
        bot.socket.close();
        bot.socket.terminate();
    }
}

// 替换为异步登录逻辑,配合错误处理
async function initBot() {
    try {
        await bot.join(process.argv[2], "a");
        console.log("Joining...".cyan);
    } catch (err) {
        console.log(err);
        await cleanup();
        process.exit(1);
    }
}

initBot();

// 处理进程退出事件
["exit", "SIGINT", "SIGUSR1", "SIGUSR2", "SIGTERM"].forEach((eventType) => {
    process.on(eventType, async (code) => {
        await cleanup();
        console.log("Exiting Process with code: ".yellow + code);
        process.exit(code);
    });
});

额外优化建议

如果修正后仍出现重复名称错误,说明服务器缓存还未释放,可以添加重试逻辑:

async function tryJoin(gameId, name) {
    let attempts = 3;
    while (attempts > 0) {
        try {
            await bot.join(gameId, name);
            console.log("Joined successfully!".cyan);
            return;
        } catch (err) {
            if (err.description === 'Duplicate name' && attempts > 1) {
                console.log("Name still in use, retrying in 3 seconds...".yellow);
                await new Promise(resolve => setTimeout(resolve, 3000));
                attempts--;
            } else {
                throw err;
            }
        }
    }
    throw new Error("Failed to join after multiple attempts");
}

// 使用重试逻辑替代直接登录
async function initBot() {
    try {
        await tryJoin(process.argv[2], "a");
    } catch (err) {
        console.log(err);
        await cleanup();
        process.exit(1);
    }
}

initBot();

另外可以检查kahoot.js-latest库的leave()方法源码,确认它是否正确向服务器发送了注销消息,如果库本身存在实现缺陷,可能需要手动构造socket消息发送注销请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:40:39