javascript - 如何连接到在 Heroku 上运行的“WebSocket”服务器?
问题描述
所以我写了一个 Node.js WebSocket 服务器并在我的电脑上进行了测试。我通过输入命令行来运行服务器node server.js
,在我的 Node.js 中我包括:
const websocketServer = new WebSocket.Server({
port: 8080
});
创建 WebSocket 服务器。然后,我编写了一个连接到该 WebSocket 服务器的 JavaScript(以及 HTML 和 CSS)客户端,我使用 Adobe 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 错误消失了???它不再打印出任何错误(开发控制台完全空白),但没有建立连接,服务器甚至不知道有人正在尝试连接......这对我来说毫无意义。为什么它会阻止错误出现,但对其他任何事情都没有任何影响?世界上到底发生了什么?(大约一分钟后什么都不做,它最终说连接超时......)
解决方案
好的,我想通了...显然 Heroku 默默地阻止了我的请求,因为它们是 ws 请求。我更改为 wss 请求,它在第一次尝试时运行良好。我不知道为什么会这样,但我很高兴它有效。
当您尝试从 https 升级到 ws 时,显然 Heroku 会出现 307 错误?我不确定为什么它不会告诉我更接近“无法从安全连接更改为不安全的 ws 连接”的内容,但我想这就是他们想要的......?
但是,这对我来说似乎很奇怪,因为我在 Heroku 中制作了另一个应用程序并成功从 https 升级到 ws 没有任何错误......我仍然不知道为什么每次我尝试它时它都会默默地失败,而它从来没有以前做过,但无论如何。我很高兴终于让它工作了。(虽然很遗憾,所有这些麻烦都是由于我在请求中漏掉了一个“s”造成的,而 Heroku 甚至无法提示我......)
非常非常非常感谢@Ders 的帮助。我非常感谢您的宝贵时间,您的帮助对我来说意义重大。
推荐阅读
- swift - node.removeAction(forKey: xx) 不工作
- python - 多个输出的自定义损失函数引发错误
- laravel - 我需要一些关于 Laravel docker 设置的建议
- docker - 为 Window 或 Mac 使用简单的 docker 桌面时,什么是 docker 机器
- sql - 如何使用 SQL 查找自首次注册以来购买的商品数量?
- swift - 尝试在框架内以编程方式实现 MKMapView
- tensorflow - 无法使用 save/pickle 保存 tensorrflow keras 量子模型
- javascript - 重定向在springboot控制器中不起作用
- android - 当 ScrollingView 到达顶部时,停止 AppBarLayout 中的 CollapsingToolbarLayout
- python - 模型预测只是验证码识别中所有类别中的一类