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

Next.js客户端用graphql-ws创建客户端报WebSocket缺失错误求助

解决Next.js中graphql-ws订阅的WebSocket实现缺失错误

错误原因

Next.js的SSR/SSG渲染机制下,组件代码会先在Node.js环境中执行预渲染,而Node.js没有原生WebSocket API。即使浏览器端自带WebSocket,服务端执行阶段graphql-ws依然找不到对应的实现,从而抛出该错误。文档示例未提及该参数,是因为示例默认只在纯浏览器环境运行,没有考虑Next.js的服务端渲染场景。

解决方案

1. 仅在浏览器环境初始化graphql-ws客户端

利用Next.js的环境判断,确保createClient只在浏览器端执行:

import { createClient } from 'graphql-ws';
import { useEffect, useState } from 'react';

export const useGraphQLWSClient = () => {
  const [client, setClient] = useState(null);

  useEffect(() => {
    const wsClient = createClient({
      url: 'ws://your-graphql-server-endpoint/graphql',
      // 浏览器环境下自动使用原生WebSocket,无需额外配置
    });
    setClient(wsClient);

    return () => {
      wsClient.dispose();
    };
  }, []);

  return client;
};

在组件中使用这个hooks时,只会在客户端挂载后初始化WebSocket客户端,避免服务端执行时的错误。

2. 显式传入浏览器原生WebSocket实现(可选)

如果上述方法仍有问题,可以显式指定webSocketImpl,但需确保只在浏览器环境传入:

import { createClient } from 'graphql-ws';

const createWSClient = () => {
  if (typeof window === 'undefined') {
    return null; // 服务端环境返回null,避免初始化
  }
  return createClient({
    url: 'ws://your-graphql-server-endpoint/graphql',
    webSocketImpl: window.WebSocket,
  });
};

这种方式可以明确告诉graphql-ws在浏览器端使用原生的WebSocket API,同时避开服务端环境的执行。

3. 避免在组件顶层直接初始化客户端

不要在组件的顶层作用域调用createClient,因为这部分代码会在服务端预渲染时执行。将初始化逻辑放在useEffect或客户端专属的工具函数中,确保仅在浏览器环境运行。

结合你的技术栈适配

如果使用react-query,可以将graphql-ws客户端的实例通过上下文(Context)提供,确保全局唯一且仅在客户端初始化:

import { createContext, useContext, useEffect, useState } from 'react';
import { createClient } from 'graphql-ws';

const GraphQLWSContext = createContext(null);

export const GraphQLWSProvider = ({ children }) => {
  const [client, setClient] = useState(null);

  useEffect(() => {
    const wsClient = createClient({
      url: 'ws://your-graphql-server-endpoint/graphql',
    });
    setClient(wsClient);

    return () => wsClient.dispose();
  }, []);

  return (
    <GraphQLWSContext.Provider value={client}>
      {children}
    </GraphQLWSContext.Provider>
  );
};

export const useGraphQLWS = () => useContext(GraphQLWSContext);

在Next.js的根组件中引入该Provider即可,确保所有子组件都能获取到客户端实例,且仅在浏览器环境初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:23:22