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

使用socket.io-client出现Maximum call stack size exceeded错误求助

解决socket.io-client中Maximum call stack size exceeded栈溢出问题

从报错栈可以看出,错误源于WebSocket的错误与关闭事件形成循环调用:

RangeError: Maximum call stack size exceeded
at [nodejs.internal.kHybridDispatch] (node:internal/event_target:824:9)
at WebSocket.dispatchEvent (node:internal/event_target:751:26)
at fireEvent (node:internal/deps/undici/undici:10966:14)
at failWebsocketConnection (node:internal/deps/undici/undici:11040:9)
at WebSocket.close (node:internal/deps/undici/undici:11650:11)
at WS.doClose (C:\Users\User\node_modules\socket.io-client\node_modules\engine.io-client\lib\transports\websocket.js:248:13)
at Transport.close (C:\Users\User\node_modules\socket.io-client\node_modules\engine.io-client\lib\transport.js:98:10)
at Socket.onClose (C:\Users\User\node_modules\socket.io-client\node_modules\engine.io-client\lib\socket.js:713:20)
at Socket.onError (C:\Users\User\node_modules\socket.io-client\node_modules\engine.io-client\lib\socket.js:691:8)
at WS. (C:\Users\User\node_modules\socket.io-client\node_modules\engine.io-client\lib\socket.js:281:10)

核心问题分析

你的代码存在致命逻辑错误:在connect事件回调内重复绑定事件监听器。由于开启了reconnect: true,每次socket断开重连成功时,connect事件都会触发,此时你会再次绑定init、new_item、close、error等事件的监听器。随着重连次数增加,同一个事件会堆积大量监听器,一旦错误或关闭事件触发,所有监听器同时执行,进而引发循环调用,最终导致栈溢出。

修复方案

1. 调整事件监听器绑定位置,避免重复绑定

将所有socket.on()的监听逻辑移到connect事件回调之外,确保每个事件只绑定一次监听器。修改后的代码如下:

async function initSocket() {
    console.log("Connecting to websocket...");

    try {
        const userData = (await axios.get(`https://${domain}/api/v2/metadata/socket`)).data;
        
        const socket = io(
            socketEndpoint,
            {
                transports: ["websocket"],
                secure: true,
                rejectUnauthorized: false,
                reconnect: true,
                extraHeaders: { 'User-agent': `${userData.user.id} API Bot` }
            }
        );

        // 事件监听器移至connect回调外,仅绑定一次
        socket.on('init', (data) => {
            if (data && data.authenticated) {
                console.log(`Successfully authenticated as ${data.name}`);

                socket.emit('filters', {
                    price_max: 9999999
                });

            } else {
                socket.emit('identify', {
                    uid: userData.user.id,
                    model: userData.user,
                    authorizationToken: userData.socket_token,
                    signature: userData.socket_signature
                });
            }
        });

        socket.on('new_item', (data) => {
            console.log(data)
        });
        
        socket.on("close", (reason) => console.log(`Socket closed: ${reason}`));
        socket.on('error', (data) => console.log(`WS Error: ${data}`));
        socket.on('connect_error', (data) => console.log(`Connect Error: ${data}`));

        socket.on('connect', () => {
            console.log(`Connected to websocket`);
            // 仅保留每次连接成功后需要执行的一次性操作
        });

    } catch (e) {
        console.log(`Error while initializing the Socket. Error: ${e}`);
    }
};

2. 降级Node.js版本至v20 LTS

你当前使用的Node.js v22.2.0是较新的版本,其内置WebSocket基于undici库,可能与socket.io-client存在兼容性问题。切换到稳定的v20 LTS版本,可规避这类底层库的兼容性bug。

3. 移除不必要的async标记

connect回调标记为async但未使用await操作,去掉该标记可避免潜在的异步逻辑问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:34:54