我正在开发一个需要连接到仅允许 TCP 连接而不是 WebSocket 连接的现有服务器的 Web 应用程序。由于现代浏览器不允许 TCP 套接字,我想出的解决方案是在某处设置一个中间件,以 websockify ( https://github.com/kanaka/websockify ) 的形式。我使用给定的 websocket 端口运行它一次,它将从该端口接收到的消息路由到服务器,并从服务器返回到我的应用程序。这种设置允许我的应用程序的多个实例一次运行并通过中间件的单个运行实例进行路由,这很好。这在本地运行良好,但我无法在 Heroku 上设置它。
我的Procfile
样子是这样的(省略了服务器主机和端口):
web: bundle exec puma -p $PORT
startserver: bundle exec ruby websockify.rb $PORT [server_host]:[server_port]
在我将更改推送到 Heroku 后,我在命令行heroku run startserver
中输入,它会响应(例如):
Starting server on :13689
0: {"listen_host"=>nil, "listen_port"=>13689, "target_host"=>[server_host], "target_port"=>[server_port]}
,这似乎表明它正在工作。有一段时间我认为这两个 $PORT 将是相同的值,但是 websocket 绑定到与 web 应用程序不同的端口,尽管我认为这是故意的行为。尽管如此,我似乎无法连接到 WebSocket,即使通过 javascript 控制台也是如此。我为控制台写了一个函数:
function test_port(schema, port) {ws = new WebSocket(schema + "://" + window.document.location.host + port, ["binary"]); ws.binaryType = "arraybuffer"; ws.onmessage = function(msg) {console.log(msg);}; ws.onclose = function() {console.log("Closed");};};
我已经在几个不同的输入上运行了这个函数,试图找出丢失了什么(除了我)。
> test_port("ws", ":13689"); // the port it should be listening on
Closed
> test_port("ws", ":42069"); // web app's port
Closed
> test_port("ws", ":5555"); // nonsense number
Closed
> test_port("ws", ""); // use default
Unexpected response code: 200
Closed
> test_port("ws", ":80"); // default
Unexpected response code: 200
Closed
> test_port("wss", ":13689");
Closed
> test_port("wss", ":42069");
Closed
> test_port("wss", ":5555");
Closed
> test_port("wss", ""); // use default
Unexpected response code: 200
Closed
> test_port("wss", ":443"); // default
Unexpected response code: 200
Closed
这些似乎都不起作用。默认设置会在立即关闭之前给出 HTTP OK 响应,但 Chrome 中似乎存在一个错误,该错误在 200 而不是预期的 101 上失败。在 websockify 启动时将端口直接设置为 443 会导致绑定错误,因为 Heroku 想要你通过他们的端口绑定。
如果我能弄清楚如何从浏览器连接到我的中间件,我想我可以弄清楚应用程序的其余部分。有人对我做错了什么有任何想法吗?感觉就像我很接近,但我不确定我还能做什么。如果您需要有关该项目的更多信息来帮助我解决问题,请告诉我。提前致谢。