如何连接到在 Heroku 上运行的“WebSocket”服务器?

时间:2021-02-17 01:25:43

标签: javascript node.js heroku websocket

所以我写了一个 Node.js WebSocket 服务器并在我的电脑上测试它。我通过在命令行中输入 node server.js 来运行服务器,并在我的 Node.js 中包含:

const websocketServer = new WebSocket.Server({
    port: 8080
});

创建 WebSocket 服务器。然后,我编写了一个连接到该 WebSocket 服务器的 JavaScript(以及 HTML 和 CSS)客户端,我使用 Adob​​e Brackets IDE 运行该客户端,并通过说 let websocket = new WebSocket("ws://localhost:8080");

一切正常。我在客户端和 WebSocket 服务器上工作了好几天,没有任何问题。

现在,我的客户端和 WebSocket 服务器已经完成,我想将我的 WebSocket 服务器部署到 Heroku 上,以便其他用户可以连接到它并使用我的客户端使用它。我的客户端被上传到一个单独的网络服务器上,用户可以访问它。

因此,我将我的 WebSocket 服务器部署到 Heroku,并将我的客户端部署到我的单独服务器上。在我的客户端中,我将 let websocket = new WebSocket("ws://localhost:8080"); 行更改为 let websocket = new WebSocket("ws://cryptic-bayou-05102.herokuapp.com");(cryptic-bayou-05102 是 Heroku 为我的 WebSocket 服务器自动生成的名称)

但是,现在当我在浏览器中加载客户端时,出现错误提示

WebSocket connection to 'ws://cryptic-bayou-05102.herokuapp.com/' failed: Error during WebSocket handshake: Unexpected response code: 307

我相信问题出在我的 WebSocket 服务器上,我有代码:

const websocketServer = new WebSocket.Server({
    port: 8080
});

我认为这段代码在 Heroku 上不起作用,因为 Heroku 可能与常规服务器的工作方式不同,因此没有“端口:8080”这样的东西,传入的请求会被定向到其他地方。根据我在网上找到的内容,我需要以某种方式配置我的 WebSocket 服务器,以根据 Heroku 分配的内容动态调整它侦听的端口。

所以...我的问题是,我该怎么做?我需要更改什么才能允许我的 WebSocket 服务器和客户端建立 WebSocket 连接?

提前致谢!任何答案都是一个巨大的帮助。

更新: 在过去的几个小时里,我一直在研究这个问题。我似乎找不到其他人收到 307 错误。我发现了许多 400/500 错误,但似乎没有人看到 307 错误... 我尝试了我在网上找到的一种解决方案,即使用 +process.env.PORT 作为运行服务器的端口,所以我尝试了一下,但它没有改变任何事情。我注销了 +process.env.PORT 的值并使用 heroku logs,它给了我 Listening on port: 18201,这是完美的,正是我想要的......但是我仍然遇到同样的错误。< /p>

最重要的是,我回过头来阅读了我之前的一个旧 Node.js 服务器+客户端项目的代码(也托管在 Heroku 上),那里的代码正是 与此处的代码相同...我正在做与之前对我有用的完全相同的事情,没有错误,除了现在我无法在不给我错误的情况下让它们工作...这非常令人沮丧。

再次编辑: 我只是想补充一下(为了澄清)我根本没有收到任何服务器端错误,并且我的服务器每 5 秒记录一次它仍在运行并且一切仍在运行。只有客户端有错误。 (此外,服务器似乎从不承认有连接请求,就像服务器甚至从未收到客户端发送的请求一样。)

另一个更新: 好的......所以我认为问题可能是我试图建立一个 ws 连接而不创建一个 http 服务器来升级,所以我改变了我的 WebSocket 服务器中的代码:

const WebSocket = require("ws");
const webSocketServerPort = +process.env.PORT || 80;

const websocketServer = new WebSocket.Server({
    port: webSocketServerPort
});

到:

const WebSocket = require("ws");
const http = require("http");
const webSocketServerPort = +process.env.PORT || 80;

const httpServer = http.createServer();

httpServer.listen(webSocketServerPort,function(){
    console.log("Server is listening on port " + webSocketServerPort);
});

const websocketServer = new WebSocket.Server({
    server: httpServer
});

当我在我的本地主机上测试该代码时,一切再次完美运行,就像没有任何改变一样(这很好!),但是当我将它部署到 Heroku 并再次尝试时...... 错误仍然存​​在那里... 我做错了什么?如果这不能解决它,那会怎样?我已经尝试了这么多小时来让它发挥作用,但我尝试过的任何事情都没有产生任何微小的变化......

还有一个更新: 以前我只在初始化 ws 连接时传入我的项目的 url,就像 let websocket = new WebSocket("ws://cryptic-bayou-05102.herokuapp.com"); 一样,我会在我的浏览器中收到 307 错误。我这样做是因为每次启动服务器时它都会侦听不同的端口,我认为 Heroku 会动态地重新路由我......但是当这显然不起作用时,我尝试在服务器启动后指定端口并显式连接到正确的端口,像这样 let websocket = new WebSocket("ws://cryptic-bayou-05102.herokuapp.com:29598");...

这也没有解决!但是它所做的是让 307 错误消失了???它不再打印出任何错误(开发控制台完全空白),但没有建立连接,服务器甚至不知道有人正在尝试连接......这对我来说毫无意义。 为什么它会阻止错误出现,但对其他任何事情都没有任何影响?世界正在发生什么? (大约一分钟后什么都不做,它最终说连接超时......)

当我尝试将 307 错误打印到开发控制台时,我看到以下内容: image of 307 error in dev console

1 个答案:

答案 0 :(得分:1)

好吧,我想通了……显然 Heroku 正在默默地阻止我的请求,因为它们是 ws 请求。我改为 wss 请求,第一次尝试时效果很好。我不知道为什么会这样,但我很高兴它有效。

当您尝试从 https 升级到 ws 时,显然 Heroku 会给出 307 错误?我不确定为什么它不会告诉我更接近于“无法从安全连接更改为不安全的 ws 连接”的内容,但我想这就是他们想要的......?

然而,这对我来说似乎很奇怪,因为我已经在 Heroku 中制作了另一个应用程序并成功地从 https 升级到 ws 没有任何错误......我仍然不知道为什么每次我尝试时它都默默地失败了它以前从未这样做过,但无论如何。我很高兴它终于可以工作了。 (虽然令人遗憾的是,所有这些麻烦都是因为我在我的请求中遗漏了一个“s”,而 Heroku 甚至无法告诉我......)

非常非常感谢@Ders 的帮助。我非常感谢您的时间,您的帮助对我来说意义重大。