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

Next.js 14中Socket.io-client连接报错:isValidUTF8不是函数求解决

解决Next.js 14中Socket.io-client连接时的isValidUTF8错误

错误信息

uncaughtException: TypeError: isValidUTF8 is not a function
at module.exports.isValidUTF8 (webpack-internal:///(ssr)/./node_modules/ws/lib/validation.js:120:53)
at Receiver.dataMessage (webpack-internal:///(ssr)/./node_modules/ws/lib/receiver.js:517:43)
at Receiver.getData (webpack-internal:///(ssr)/./node_modules/ws/lib/receiver.js:446:17)
at Receiver.startLoop (webpack-internal:///(ssr)/./node_modules/ws/lib/receiver.js:148:22)
at Receiver._write (webpack-internal:///(ssr)/./node_modules/ws/lib/receiver.js:83:10)
at writeOrBuffer (node:internal/streams/writable:392:12)
at _write (node:internal/streams/writable:333:10)
at Writable.write (node:internal/streams/writable:337:10)
at Socket.socketOnData (webpack-internal:///(ssr)/./node_modules/ws/lib/websocket.js:1272:35)
at Socket.emit (node:events:514:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Readable.push (node:internal/streams/readable:234:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23)
at TCP.callbackTrampoline (node:internal/async_hooks:130:17)

项目代码

app/page.js

'use client';

import { socket } from '@/app/socket';

import { useEffect, useMemo, useState } from 'react';

const Home = () => {

  useEffect(() => {
    const onNewConnection = async () =>{};
    socket.on('newConnection', onNewConnection);
    return () => {
      socket.disconnect();
    };
  }, []);

  useEffect(() => {
    const onNewTrace = () => {};
    const onExpiredTrace = () => {};
    socket.on('newTrace', onNewTrace);
    socket.on('expiredTrace', onExpiredTrace);

  }, [socket]);

};
export default Home;

app/socket.js

import { io } from 'socket.io-client';

export const socket = io('http://0.0.0.0:8083/');

解决方案

这个错误源于Socket.io依赖的ws库在Next.js的SSR环境中,调用Node.js内置的isValidUTF8方法时出现兼容问题,核心是WebSocket客户端逻辑被意外在服务器端执行了。以下是几种可行的解决方法:

1. 确保Socket仅在客户端初始化

修改socket.js,判断环境后再创建Socket实例,避免服务器端执行WebSocket初始化:

import { io } from 'socket.io-client';

// 只在浏览器环境创建Socket实例
export const getSocket = () => {
  if (typeof window === 'undefined') {
    return null;
  }
  return io('http://0.0.0.0:8083/');
};

然后在page.js中用useMemo初始化Socket,并添加事件监听的清理逻辑(避免内存泄漏):

'use client';

import { getSocket } from '@/app/socket';
import { useEffect, useMemo } from 'react';

const Home = () => {
  const socket = useMemo(() => getSocket(), []);

  useEffect(() => {
    if (!socket) return;

    const onNewConnection = () => {};
    socket.on('newConnection', onNewConnection);

    // 组件卸载时移除监听并断开连接
    return () => {
      socket.off('newConnection', onNewConnection);
      socket.disconnect();
    };
  }, [socket]);

  useEffect(() => {
    if (!socket) return;

    const onNewTrace = () => {};
    const onExpiredTrace = () => {};
    socket.on('newTrace', onNewTrace);
    socket.on('expiredTrace', onExpiredTrace);

    // 组件卸载时移除监听
    return () => {
      socket.off('newTrace', onNewTrace);
      socket.off('expiredTrace', onExpiredTrace);
    };
  }, [socket]);

  return <div>Home Page</div>;
};

export default Home;

2. 调整Next.js Webpack配置

在next.config.js中添加Webpack配置,让服务器端忽略ws库的打包,客户端环境下禁用相关Node.js依赖:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config, { isServer }) => {
    if (isServer) {
      // 服务器端将ws标记为外部依赖,避免Webpack处理
      config.externals.push('ws');
    } else {
      // 客户端环境下禁用ws依赖的Node.js模块
      config.resolve.fallback = {
        ...config.resolve.fallback,
        ws: false,
        bufferutil: false,
        utf-8-validate: false,
      };
    }
    return config;
  },
};

module.exports = nextConfig;

3. 更新依赖版本

确保socket.io-client和ws版本兼容,升级到最新稳定版:

npm install socket.io-client@latest
# 或者指定兼容的ws版本
npm install ws@8.14.2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 19:33:14