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

NextJs集成Apollo GraphQL Subscription时WebSocket报错如何解决

错误原因
  • 报错的核心是Next.js存在服务端渲染(SSR/SSG)阶段,代码会先在Node.js服务端执行一次,而WebSocket仅在浏览器环境存在,服务端无原生实现
  • 你的代码存在两个明显问题:
    1. 额外引入了仅Node.js环境使用的ws库,浏览器端自带全局WebSocket对象,无需手动导入传入
    2. 未做环境区分,服务端运行时直接初始化了wsLink,触发环境不兼容报错
修复步骤
  1. 删除import ws from 'ws';这行导入代码,同时删除WebSocketLink配置中传入的ws参数
  2. 增加环境判断逻辑,仅在浏览器环境(typeof window !== 'undefined')下初始化wsLink,服务端直接使用httpLink处理所有请求
  3. 如果你使用的是Next.js 13+的App Router,需要在client.js文件顶部添加'use client';标识,标记为客户端组件
完整修改后代码
// Next.js 13+ App Router 需要添加下面这行
// 'use client';
import {
    ApolloClient,
    ApolloLink,
    HttpLink,
    InMemoryCache,
    split,
  } from '@apollo/client';
  import {WebSocketLink} from '@apollo/client/link/ws';
  import {getMainDefinition} from '@apollo/client/utilities';

  const httpUrl = 'http://localhost:3000/graphql';
  const wsUrl = 'ws://localhost:3000/graphql';
  
  const httpLink = ApolloLink.from([
    new ApolloLink((operation, forward) => {
      return forward(operation);
    }),
    new HttpLink({uri: httpUrl}),
  ]);
  
  // 仅浏览器环境初始化wsLink
  let wsLink = null;
  if (typeof window !== 'undefined') {
    wsLink = new WebSocketLink({
      uri: wsUrl,
      options: {
        connectionParams: () => {},
        lazy: true,
        reconnect: true,
      }
    });
  }
  
  function isSubscription(operation) {
    const definition = getMainDefinition(operation.query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  }
  
  const client = new ApolloClient({
    cache: new InMemoryCache(),
    // 服务端无wsLink时直接走httpLink
    link: typeof window !== 'undefined' ? split(isSubscription, wsLink, httpLink) : httpLink,
    defaultOptions: {query: {fetchPolicy: 'no-cache'}},
  });
  
  export default client;

内容的提问来源于stack exchange,提问作者Tâm Đỗ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:18:03