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

Next.js + tRPC集成WebSockets订阅的实现方案问询

在Next.js中集成tRPC WebSocket订阅的正确方案

问题根因

你遇到的fs等Node.js库找不到的错误,本质是两个核心原因:

  1. Next.js的API路由是基于HTTP的无服务器短连接函数,不支持WebSocket长连接,无法直接在API路由内启动WebSocket服务;
  2. Next.js打包API路由时会使用浏览器兼容的配置,自动排除Node.js核心模块,而ws库依赖这些模块,导致打包或运行时报错。

下面分两种部署场景给出解决方案:


场景1:自定义服务器部署(如Docker、EC2)

适合可以自行控制服务器环境的场景,直接通过自定义Node.js服务器集成tRPC WebSocket。

1. 安装依赖

npm install ws @trpc/server @trpc/client @types/ws
# 或使用 yarn/pnpm

2. 创建自定义服务器文件

在项目根目录创建server.ts:

import { createServer } from 'http';
import { parse } from 'url';
import next from 'next';
import { applyWSSHandler } from '@trpc/server/adapters/ws';
// 导入你的tRPC路由和上下文
import { appRouter } from './server/trpc/router/_app';
import { createContext } from './server/trpc/context';

const isDev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev: isDev });
const nextRequestHandler = nextApp.getRequestHandler();

// 启动Next.js应用并绑定HTTP服务器
nextApp.prepare().then(() => {
  const httpServer = createServer((req, res) => {
    const parsedUrl = parse(req.url!, true);
    nextRequestHandler(req, res, parsedUrl);
  });

  // 集成tRPC WebSocket服务
  applyWSSHandler({
    wss: new WebSocket.Server({ server: httpServer }),
    router: appRouter,
    createContext,
  });

  const PORT = process.env.PORT || 3000;
  httpServer.listen(PORT, () => {
    console.log(`服务运行在 http://localhost:${PORT}`);
    console.log(`WebSocket服务已就绪`);
  });
});

3. 修改启动脚本

更新package.json的scripts字段,用自定义服务器替代默认的Next.js启动命令:

{
  "scripts": {
    "dev": "node server.ts",
    "build": "next build",
    "start": "NODE_ENV=production node server.ts"
  }
}

4. 客户端配置WebSocket链接

在tRPC Provider中同时配置HTTP(用于普通请求)和WebSocket(用于订阅)链接:

import { createTRPCReact } from '@trpc/react-query';
import { httpBatchLink, wsLink, createWSClient } from '@trpc/client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { AppRouter } from '../server/trpc/router/_app';

export const trpc = createTRPCReact<AppRouter>();
const queryClient = new QueryClient();

export function TRPCProvider({ children }: { children: React.ReactNode }) {
  const wsClient = createWSClient({
    url: process.env.NEXT_PUBLIC_WS_URL || 'ws://localhost:3000',
  });

  const trpcClient = trpc.createClient({
    links: [
      wsLink({ client: wsClient }),
      httpBatchLink({ url: '/api/trpc' }),
    ],
  });

  return (
    <QueryClientProvider client={queryClient}>
      <trpc.Provider client={trpcClient} queryClient={queryClient}>
        {children}
      </trpc.Provider>
    </QueryClientProvider>
  );
}

场景2:Vercel无服务器部署

Vercel的无服务器函数不支持WebSocket长连接,建议用**Server-Sent Events (SSE)**替代WebSocket实现tRPC订阅:

1. 配置tRPC路由的订阅端点

// server/trpc/router/notification.ts
import { z } from 'zod';
import { publicProcedure, router } from '../trpc';
import { Observable } from '@trpc/server/observable';

export const notificationRouter = router({
  subscribeToUpdates: publicProcedure.subscription(() => {
    return new Observable((emit) => {
      // 模拟实时推送逻辑,替换为你的业务代码
      const interval = setInterval(() => {
        emit.next({ content: '新消息通知' });
      }, 5000);

      // 清理函数:客户端取消订阅时触发
      return () => clearInterval(interval);
    });
  }),
});

2. 客户端配置SSE链接

替换WebSocket链接为SSE链接,同时保留HTTP链接:

import { createTRPCReact } from '@trpc/react-query';
import { httpBatchLink, sseLink } from '@trpc/client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { AppRouter } from '../server/trpc/router/_app';

export const trpc = createTRPCReact<AppRouter>();
const queryClient = new QueryClient();

export function TRPCProvider({ children }: { children: React.ReactNode }) {
  const trpcClient = trpc.createClient({
    links: [
      sseLink({ url: '/api/trpc' }),
      httpBatchLink({ url: '/api/trpc' }),
    ],
  });

  return (
    <QueryClientProvider client={queryClient}>
      <trpc.Provider client={trpcClient} queryClient={queryClient}>
        {children}
      </trpc.Provider>
    </QueryClientProvider>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 04:18:14