Heroku + node.js:我有一个使用多个端口的服务器。如何让 Heroku 分配它们?
Posted
技术标签:
【中文标题】Heroku + node.js:我有一个使用多个端口的服务器。如何让 Heroku 分配它们?【英文标题】:Heroku + node.js: I have a server which uses multiple ports. How can I get Heroku to allocate them? 【发布时间】:2016-10-04 19:56:06 【问题描述】:嗯,我会尽量说得更清楚..
在我用 node.js 编写的应用服务器中,我有多个端口的内部代理:
在我的8080
端口我有我的rest api。
在我的3000
端口我有我的推送服务器和聊天。
我使用 npm 包 subdomain-router 进行到端口的内部路由,将代理返回到这些端口的“前端”中的子域公开。代码演示: (<some-app>
显然不是应用的真名)
require('subdomain-router')
(
host: '<some-app>.herokuapp.com',
subdomains:
'': 8080, // <some-app>.herokuapp.com <=> ::8080 --WORKS--
'api': 8080, // api.<some-app>.herokuapp.com <=> ::8080
'chat': 3000, // chat.<some-app>.herokuapp.com <=> ::3000
'push': 3000 // push.<some-app>.herokuapp.com <=> ::3000
).listen(process.env.PORT || 5000);
API 工作得很好,虽然我无法通过<some-app>.herokuapp.com:8080
访问它,但只能通过<some-app>.herokuapp.com
并让内部的subdomain-router
模块发挥它的魔力。
另外,我无法访问子域。尝试访问 api.<some-app>.herokuapp.com
时,我从 heroku 收到 No such app
错误页面。
TL;DR 访问 <some-app>.herokuapp.com
有效(重定向到我的 API 的 /v1
路径),但无法访问 <some-app>.herokuapp.com:8080
、<some-app>.herokuapp.com:3000
或 chat.<some-app>.herokuapp.com
。
当尝试通过在 url 中指定端口来访问我的 API 时(像这样:<some-app>.herokuapp.com:8080
),我在浏览器(谷歌浏览器)中收到以下错误:ERR_CONNECTION_REFUSED
。
我有根据的猜测说这可能与在 heroku 中打开端口有关,但我不知道该怎么做(尝试谷歌搜索 ofc)。 它并没有解释为什么我无法访问子域。
希望能对此问题有所了解。 我是 heroku 的新手,它变得非常令人沮丧。
谢谢! 阿米特
【问题讨论】:
【参考方案1】:好的,经过一番研究,我发现在 Heroku 中打开端口是禁用并且不允许。
解决此问题的唯一方法是使用子域,然后在应用内使用代理模块(例如我使用的subdomain-router
)。
但是 - Heroku 不允许您在其域上创建子域,这意味着 your-app.herokuapp.com
是固定的,不能有子域。
在 Heroku 手册中,他们要求您拥有自己的域和 dns 提供商来执行此操作,方法是在域设置的 dns 表中创建一个 A-alias (CNAME),这将引用您的应用程序 herokuapp 域,然后使用命令heroku domains:add
将您的域添加到允许的来源列表。
您可以阅读更多here。它提供了您需要的所有信息。
希望对一些人有所帮助。
【讨论】:
是的,你只有一个端口,但你可以通过那里为你的 websockets 以及 HTTP 请求提供服务。 @Antoine 如何在同一个端口处理 HTTP 请求和 TCP (websocket) 消息? @Antoine 我和 vin 在一起 - 它是如何工作的?我也面临同样的问题,但为了能够处理一些 HTTP 请求而不得不做所有这些工作真的很烦人......【参考方案2】:我知道这是一篇旧帖子,但我想提供最新的回复以供参考和将来使用:
如果您使用的是 socket-io,绑定到同一个端口很容易。其他 websocket 库应该有类似的方法(来自https://github.com/socketio/socket.io#how-to-use):
结合快递 从 3.0 开始,快速应用程序已成为您传递给 http 或 http Server 实例的请求处理程序函数。您需要将 Server 传递给 socket.io,而不是 express 应用程序函数。还要确保在服务器而不是应用程序上调用 .listen。
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => /* … */ );
server.listen(3000);
现在,您将拥有流经单个端口的 http 和 ws 流量(Heroku 不会单独路由 http/tcp,如果这样做,您的 websocket 将无法工作)。
由于环境奇偶校验和测试,我更喜欢这种方法,即无需设置子域或端口路由
【讨论】:
【参考方案3】:我今天也了解到了这个,我了解到如果你在 Heroku 的一个端口上运行一个服务,你仍然可以在本地访问它。不适用于上述用户的问题,但它确实解决了我的问题,导致我提出了这个问题。
【讨论】:
以上是关于Heroku + node.js:我有一个使用多个端口的服务器。如何让 Heroku 分配它们?的主要内容,如果未能解决你的问题,请参考以下文章
Node.js - 在 Heroku 上使用 MongoHQ 连接到 MongoDB
如何同步 Node js 应用程序、git 和 Heroku?
从 Heroku 上的 Node.js 连接到 CloudSQL