部署结合Socket.IO的GraphQL API到Heroku的端口相关问题咨询
Heroku 双端口 Socket.IO + GraphQL 架构部署解答
核心结论
Heroku 单个应用(单 dyno)默认仅对外开放 1个端口,两个服务独立监听不同端口的原生架构无法直接部署。你可以通过同端口路径路由的方案调整架构后正常部署,不需要放弃当前技术选型。
可落地的调整方案
- 方案1:单应用同端口挂载双服务(最推荐)
把 GraphQL 和 Socket.IO 都挂载到同一个 HTTP 服务实例下,通过不同路径区分请求,两者共用同一个端口,完全符合 Heroku 的端口规则。示例逻辑如下:const express = require('express'); const { createServer } = require('http'); const { Server } = require('socket.io'); const { graphqlHTTP } = require('express-graphql'); const yourGraphQLSchema = require('./schema'); const app = express(); const httpServer = createServer(app); // 挂载 GraphQL 服务,走 /graphql 路径 app.use('/graphql', graphqlHTTP({ schema: yourGraphQLSchema, graphiql: true })); // 挂载 Socket.IO 服务,走 /socket.io 路径 const io = new Server(httpServer, { path: '/socket.io', cors: { origin: "你的前端域名" } }); io.on('connection', (socket) => { // Socket.IO 业务逻辑 }); // 必须读取 Heroku 分配的 PORT 环境变量,不要写死固定端口 const PORT = process.env.PORT || 4000; httpServer.listen(PORT, () => { console.log(`服务已启动,端口:${PORT}`); }); - 方案2:拆分为两个独立 Heroku 应用
如果业务需要两个服务完全解耦、独立迭代扩缩容,可以把 GraphQL 和 Socket.IO 拆成两个独立的代码仓库,分别部署为两个不同的 Heroku 应用,每个应用各自监听 Heroku 分配的端口,前端分别调用两个应用的域名即可。该方案运维成本更高,适合中大型项目。
部署注意事项
- 代码中禁止写死固定监听端口,必须读取
process.env.PORT变量,该变量由 Heroku 运行时自动分配 - Socket.IO 服务需要单独配置跨域规则,允许前端域名访问
- Heroku 免费 dyno 的休眠规则对该架构同样生效,需要长期在线可升级至付费实例
内容的提问来源于stack exchange,提问作者Sub-Zero
相关产品推荐
相关产品推荐

