我正在开发一个需要连接到现有服务器的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 OK响应,但是Chrome中似乎有一个错误,它在200而不是预期的101上失败。在websockify的启动时将端口直接设置为443会导致绑定错误,因为Heroku想要你通过他们的端口绑定。
如果我能弄清楚如何从浏览器连接到我的中间件,我想我可以找出应用程序的其余部分。有没有人对我做错了什么有任何想法?我觉得我很亲密,但我不确定我还能做些什么。如果您需要有关该项目的更多信息以帮助我排除故障,请与我们联系。提前谢谢。
答案 0 :(得分:0)
我得出结论,websockify是错误的工具。与heroku应用程序的Websocket连接被路由到默认端口(ws为80,wss为443),但是您不能通过绑定到端口来访问它们。你收到它们作为HTTP请求(我想?),并且必须检查自己是否正在请求Websocket连接。我不知道websockify是否会让我这样做,但它肯定不是我运行它的方式,因此我更容易在Ruby中编写自己的小型中间件,将websocket消息路由到TCP服务器和TCP消息通过websocket连接。一旦我弄清楚websocket将尝试连接的位置,并在此网站https://devcenter.heroku.com/articles/ruby-websockets的帮助下,这是相当简单的。