首页 > 解决方案 > 如何连接到在 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 运行该客户端,并通过说,与在我的本地主机上运行的 WebSocket 服务器建立了 WebSocket 连接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完美的东西,正是我想要的......但是我仍然遇到同样的错误。

最重要的是,我回过头来阅读我的一个较旧的 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 错误打印到开发控制台时,我看到以下内容: 开发控制台中 307 错误的图像

标签: javascriptnode.jsherokuwebsocket

解决方案


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

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

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

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


推荐阅读