如何在Zeit Now 2.0中获取Apollo Server的WS端点以启用subscription
获取Zeit Now 2.0中Apollo Server的WebSocket端点问题
首先得明确一个关键限制:Zeit Now 2.0(现在已更名为Vercel)的Serverless Functions原生不支持WebSocket长连接——因为Serverless函数是短生命周期的(通常执行上限在10秒左右),没法维持WebSocket需要的持久连接。所以你没法直接从Now 2.0获取WS端点来支持Apollo Subscription。
不过有两个可行的替代方案来实现订阅功能:
方案1:改用Server-Sent Events (SSE) 作为订阅传输层
这是适配Now 2.0 Serverless环境最直接的方案,不需要依赖WebSocket,完全通过HTTP协议实现订阅推送。
服务端配置
- 安装必要的依赖:
npm install @apollo/server @apollo/server-plugin-subscriptions-sse graphql
- 在Apollo Server初始化时添加SSE订阅插件:
import { ApolloServer } from '@apollo/server'; import { startServerAndCreateHandler } from '@apollo/server/express4'; import { ApolloServerPluginSubscriptionsSSE } from '@apollo/server-plugin-subscriptions-sse'; import express from 'express'; const app = express(); const server = new ApolloServer({ typeDefs, // 你的GraphQL schema resolvers, // 你的解析器 plugins: [ApolloServerPluginSubscriptionsSSE()], }); await server.start(); app.use('/api/graphql', express.json(), startServerAndCreateHandler(server)); export default app;
客户端配置
使用graphql-sse客户端替代原来的WebSocket客户端:
import { createClient } from 'graphql-sse'; const client = createClient({ url: 'https://your-now-deployment-url/api/graphql', // 直接用你的HTTPS端点 }); // 订阅示例 const subscription = client.subscribe({ query: `subscription { newMessage { id content } }`, }, { next: (data) => console.log('收到消息:', data), error: (err) => console.error('订阅错误:', err), complete: () => console.log('订阅完成'), }); // 取消订阅时调用 // subscription.unsubscribe();
方案2:部署独立的WebSocket服务(若坚持用WS)
如果必须使用WebSocket,你需要在支持WebSocket的平台(比如Heroku、DigitalOcean App Platform等)单独部署一个Apollo WebSocket订阅服务器,然后在Now 2.0的Apollo Server中,将订阅请求代理到这个独立服务。
独立WebSocket服务示例(用subscriptions-transport-ws)
import { createServer } from 'http'; import { SubscriptionServer } from 'subscriptions-transport-ws'; import { execute, subscribe } from 'graphql'; import { schema } from './your-schema'; const server = createServer(); SubscriptionServer.create({ schema, execute, subscribe, }, { server, path: '/subscriptions', }); server.listen(4000, () => { console.log('WebSocket订阅服务器运行在ws://localhost:4000/subscriptions'); });
部署这个服务后,你就能得到一个WS/WSS端点,然后在Apollo Client中直接配置这个端点即可。
内容的提问来源于stack exchange,提问作者Sujoy Saha




