我正在开发一个web应用程序,它需要连接到一个只允许TCP连接的现有服务器,而不是WebSocket连接。由于现代浏览器不允许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]}这似乎表明它起作用了。有一段时间,我认为这两个$PORTs的值是相同的,但是websocket绑定到一个与web应用程序不同的端口,尽管我认为这是有意的行为。不过,即使是通过javascript控制台,我似乎也无法连接到WebSocket。我为控制台编写了一个函数:
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响应,但Chrome中似乎存在一个错误,它在200而不是预期的101上失败。在websockify启动时直接将端口设置为443会导致绑定错误,因为Heroku希望您通过它们的端口绑定。
我认为,如果我能够从浏览器中找到连接到中间件的方法,我就可以计算出应用程序的其余部分。有人知道我做错了什么吗?感觉我很接近,但我不确定我还能做些什么。如果您需要更多关于该项目的信息,请告诉我,以帮助我解决它。提前谢谢。
发布于 2013-12-16 08:27:09
我得出的结论是,websockify是这项工作的错误工具。到heroku应用程序的Websocket连接被路由到默认端口( ws为80,wss为443 ),但您不能通过绑定到端口来访问它们。您将它们作为HTTP请求来接收(我认为?),并且必须检查它是否请求Websocket连接。我不知道websockify是否会让我这么做,但这肯定不是我运行它的方式,所以我更容易用Ruby编写自己的小型中间件,通过websocket连接将websocket消息路由到TCP服务器和TCP消息。一旦我知道websocket将尝试连接到哪里,并且在这个站点https://devcenter.heroku.com/articles/ruby-websockets的帮助下,这是相当简单的。
https://stackoverflow.com/questions/19988047
复制相似问题