在使用Action Cable时将Ruby on Rails应用程序部署到Heroku(Puma端口侦听)

编程入门 行业动态 更新时间:2024-10-27 23:28:06
本文介绍了在使用Action Cable时将Ruby on Rails应用程序部署到Heroku(Puma端口侦听)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有Action Cable在本地主机环境中工作,在这种情况下,我使用包含 #/ bin / bash bundle exec puma -p 28080 cable / config.ru

一旦发生这种情况,美洲狮服务器启动并正在监听28080端口和运行本地服务器的端口。通过在线狩猎,我无法找到一个能够告诉我一种在heroku上模拟这种方式的地方,或者让我的服务器始终在同一个端口上启动的方式(尽管我不知道这是否会给我想要的结果)

我有一个JavaScript文件设置用来创建与该端口相关的消费者。

// =需要连接线 // = require_self // = require_tree。 this.App = {}; App.cable = Cable.createConsumer('ws://127.0.0.1:28080');

我想我需要更改127.0.0.1部分以及部署到heroku工作,但我不确定。我试图切断28080部分并将其替换为ENV ['PORT'],但它表示它是一个未知的变量,即使我有一个puma.rb文件,它的端口设置为

...(仅文件的一部分) rackup DefaultRackup 端口ENV ['PORT'] || 3000 环境ENV ['RACK_ENV'] || 'development' ...

因此,在我看来,ENV ['PORT' ]被定义为当我检查heroku日志时,puma服务器将会是 2015-07-26T06:50:25.278030+ 00:00 heroku [web.1]:用命令`bin / rails server -p 48875 -e production`启动进程 2015-07-26T06:50:30.760680 + 00:00 app [web.1]: =>启动Puma 2015-07-26T06:50:30.760714 + 00:00 app [web.1]:=> Rails 4.2.1应用程序从0.0.0.0:48875开始生产 2015-07-26T06:50:30.760716 + 00:00 app [web.1]:=>为更多启动选项运行`rails server -h` 2015-07-26T06:50:30.760718 + 00:00 app [web.1]:=> Ctrl-C关闭服务器 2015-07-26T06:50:31.578843 + 00:00 app [web.1]:Puma 2.12.2开始... 2015-07-26T06:50: 31.578851 + 00:00 app [web.1]:*最低线程数:0,最多线程数:16 2015-07-26T06:50:31.578859 + 00:00 app [web.1]:*环境:生产 2015-07-26T06:50:31.578861 + 00:00 app [web.1]:*听取tcp://0.0.0.0:48875

如果有什么不清楚的地方,我很抱歉,如果我遗漏任何东西,我会很乐意提供更多信息。 编辑

以下是/app/assets/javascripts/channels/index.js.erb中的更新代码

// =需要连接线 // = require_self // = require_tree。 this.App = {}; App.cable = Cable.createConsumer('<%= ENV [CABLE_SERVER]%>');

其中ENV [CABLE_SERVER]指向 ws:// the- action-cable-server.herokuapp 。这个变量存储在rails server env变量中。

解决方案

Issue < Heroku有一些限制:路由器:它只会听取端口80和443.换句话说,您无法在任何Heroku应用程序上打开固定端口。在ActionCable服务器案例中,无法打开固定端口并将WebSocket流量路由到它。因此,无论是Heroku允许这样的事情(我怀疑)或我们使用的解决方法。

解决方法

版本0.0.3的actioncable,这里是我使用的解决方法。

这个想法是没有一个Heroku应用程序,但有两个:一个用于主轨服务器,一个用于ActionCable服务器。两者都可以在端口80(或443)上运行。

从一个代码库运行两个不同的服务器只需要两个Procfiles:一个用于rails,一个用于action电缆。有一个 buildpack 来处理这个问题。要使用它,您还需要多个buildpack 。

假设您的两个Heroku应用程序名为 rails 和 actioncable 。

使用以下命令在项目的根目录下创建一个 .buildpacks 文件:

github/cantino/heroku-selectable-procfile github/heroku/heroku-buildpack-ruby

在 rails 和 actioncable ,使用 github/heroku/heroku-buildpack-multi创建一个env var BUILDPACK_URL 。 git

现在对于Procfiles,我选择保留 Procfile 与工头并创建两个自定义的: Procfile.rails 和 Procfile.actioncable 。

在 Procfile.rails 中,描述了所有需要的dynos 除了操作有线服务器,例如:

web:bundle exec puma -C config / puma / config.rb clockwork:bundle exec clockwork lib / clockwork.rb worker:bundle exec rake jobs:work

在 Procfile.actioncable 中,您只描述动作有线服务器:

web:bundle exec puma -p $ PORT cable / config.ru

请注意,我们使用的是 web dyno,它将在端口80(或443)上安装动作电缆服务器。

注意您需要将puma配置文件 config / puma.rb 移至自定义位置。我选择 config / puma / config.rb 。 config / puma.rb 是启动puma而没有任何特定配置文件时的默认位置,这正是 Procfile.actioncable 。这可能会导致意外的行为(请参阅下面的注释)。

现在,在 rails 上,创建一个env var PROCFILE_PATH 与 Procfile.rails 和 actioncable ,创建一个env var PROCFILE_PATH with Procfile.actioncable 。

的环境变量, actioncable 需要 rails 中所有启动actioncable服务器所需的所有环境变量,比如DATABASE_URL或任何凭证。

现在至关重要的一步:我们如何连接 rails 和 actioncable 在一起?这只需使用相同的 Redis实例即可完成。 rails 会将消息放在Redis上, actioncable 会听取它们并采取相应的行动。这就是为什么两个都必须定位相同 Redis实例。如果你使用Heroku Redis,你只需在 rails 和中设置 REDIS_URL strong> actioncable 。这里是有线服务器的配置文件 cable.yml :

制作:&制作:网址:<%= ENV [REDIS_URL]%> :超时:1 开发:& development :url:<%= ENV [REDIS_URL]%> :timeout:1 :inline:true test:* development

最后一步是更改JavaScript文件,以便我们可以控制Action Cable服务器的位置。

将 .js 后缀更改为我们可以使用env var来做到这一点。如果需要的话.js.erb

// =需要连接线 // = require_self // = require_tree。 this.App = {}; App.cable = Cable.createConsumer('<%= ENV [CABLE_SERVER]%>');

这个 CABLE_SERVER 变量现在可以指向 ws://127.0.0.1:28080 本地和 rails ,值将为 actioncable 。

现在您已准备好将代码部署到 rails ,如果您有任何客户端身份验证,则不能使用 cookies 示例。你现在有两个Heroku应用程序,他们不能共享一个cookie。我想你仍然可以解决方法使用多个子域名的cookie。

  • 你现在有两个部署目标需要维护。
  • 您有多个Procfiles需要维护。希望随着时间的推移,将会有一个更简单的解决方法:)
  • 替代品
    • 我们可以相同的服务器使用简单的中间件处理普通Web流量和 websocket流量。 这里是。
    • 至于rails 5 beta2,动作有线服务器现在也可以侧面安装以及您的主要应用程序。有两种不同的服务器仍然有意义:您可以逐个扩展它们。

    hth

    I have got Action Cable working in a local host environment and in this situation I start the Puma server using a simple file containing

    # /bin/bash bundle exec puma -p 28080 cable/config.ru

    Once this happens the puma server starts and is listening to this 28080 port and the port the local server is running on. Through hunting online I couldn't find a place that would tell me a way to emulate this on heroku or a way to have my server always start on the same port (though I don't know if that would give me the desired result either)

    I have a javascript file set up to create a consumer related to that port.

    //= require cable //= require_self //= require_tree . this.App = {}; App.cable = Cable.createConsumer('ws://127.0.0.1:28080');

    I imagine I'll need to change the 127.0.0.1 part as well for the deploy to heroku to work as well but I'm not certain. I attempted to cut off the 28080 part and replace it with ENV['PORT'] but it said it was an unknown variable even though I have a puma.rb file set up which has its port set as

    ... (only part of the file) rackup DefaultRackup port ENV['PORT'] || 3000 environment ENV['RACK_ENV'] || 'development' ...

    So it seemed to me that ENV['PORT'] was being defined as when I check the heroku logs the puma server will be

    2015-07-26T06:50:25.278030+00:00 heroku[web.1]: Starting process with command `bin/rails server -p 48875 -e production` 2015-07-26T06:50:30.760680+00:00 app[web.1]: => Booting Puma 2015-07-26T06:50:30.760714+00:00 app[web.1]: => Rails 4.2.1 application starting in production on 0.0.0.0:48875 2015-07-26T06:50:30.760716+00:00 app[web.1]: => Run `rails server -h` for more startup options 2015-07-26T06:50:30.760718+00:00 app[web.1]: => Ctrl-C to shutdown server 2015-07-26T06:50:31.578843+00:00 app[web.1]: Puma 2.12.2 starting... 2015-07-26T06:50:31.578851+00:00 app[web.1]: * Min threads: 0, max threads: 16 2015-07-26T06:50:31.578859+00:00 app[web.1]: * Environment: production 2015-07-26T06:50:31.578861+00:00 app[web.1]: * Listening on tcp://0.0.0.0:48875

    I apologize if anything is unclear and would be happy to provide any more information if I left anything out.

    EDIT

    Here is the updated code in /app/assets/javascripts/channels/index.js.erb

    //= require cable //= require_self //= require_tree . this.App = {}; App.cable = Cable.createConsumer('<%= ENV["CABLE_SERVER"] %>');

    where ENV["CABLE_SERVER"] points to ws://the-action-cable-server.herokuapp. This variable is stored in the rails server env variables.

    解决方案

    Issue

    There are some limits to the Heroku router: it will only listen to ports 80 and 443. In other words, you can't open a fixed port on any Heroku application. In the ActionCable server case, there is no way to open a fixed port and get the websocket traffic routed to it. So either Heroku allows such things (which I doubt) or we use a workaround.

    Workaround

    As of version 0.0.3 of actioncable, here is the workaround I used.

    The idea is to have not one Heroku application but two: one for the main rails server and one for the ActionCable server. Both would run on port 80 (or 443).

    To run two different servers from one codebase is simply a matter of having two Procfiles: one for rails and one for action cable. There is a buildpack to handle this. To use it, you also need the multi buildpack.

    Let's say you have your two Heroku applications called rails and actioncable.

    Create a .buildpacks file in the root of your project with this:

    github/cantino/heroku-selectable-procfile github/heroku/heroku-buildpack-ruby

    On rails and actioncable, create an env var BUILDPACK_URL with github/heroku/heroku-buildpack-multi.git

    Now for the Procfiles, I choose to keep Procfile for running everything locally with foreman and create two custom ones: Procfile.rails and Procfile.actioncable.

    In Procfile.rails, you describe all the needed dynos except the action cable server, eg.:

    web: bundle exec puma -C config/puma/config.rb clockwork: bundle exec clockwork lib/clockwork.rb worker: bundle exec rake jobs:work

    In Procfile.actioncable, you describe only the action cable server:

    web: bundle exec puma -p $PORT cable/config.ru

    Note that we are using a web dyno which will mount the action cable server on port 80 (or 443).

    CAUTION You need to move the puma config file config/puma.rb to a custom location. I choose config/puma/config.rb. config/puma.rb is the default location when you start puma without any specific config file, which is what we have in Procfile.actioncable. This can lead to unexpected behaviors (see the comments below).

    Now, on rails, create an env var PROCFILE_PATH with Procfile.rails and on actioncable, create an env var PROCFILE_PATH with Procfile.actioncable.

    Speaking of env vars, the actioncable needs all the env vars from rails that are necessary to start the actioncable server like the DATABASE_URL or any credentials.

    Now the crucial step: how do we connect rails and actioncable together? This is simply done by using the same Redis instance. rails will put messages on Redis and actioncable will listen to them and act accordingly. That's why both have to target the same Redis instance. If you using Heroku Redis, you just need to set REDIS_URL with the same value on rails and actioncable. Here is the config file for the cable server cable.yml:

    production: &production :url: <%= ENV["REDIS_URL"] %> :timeout: 1 development: &development :url: <%= ENV["REDIS_URL"] %> :timeout: 1 :inline: true test: *development

    The final step is changing the javascript file so that we can control where is the Action Cable server. We can do this by using an env var.

    Change the .js suffix into .js.erb if necessary.

    //= require cable //= require_self //= require_tree . this.App = {}; App.cable = Cable.createConsumer('<%= ENV["CABLE_SERVER"] %>');

    This CABLE_SERVER variable can now point to ws://127.0.0.1:28080 locally and on rails, the value will be the url of actioncable.

    Now you're ready to deploy the code on rails and actioncable.

    Caveats/Drawbacks
    • on actioncable, if you have any client authentication, you can't use cookies like in the examples. You have now two Heroku apps and they can't share a cookie. I guess you can still workaround this using a cookie for multiple subdomains.
    • you have now two deploy targets to maintain.
    • you have multiple Procfiles to maintain.
    • hopefully, with time, there will be an easier workaround :)
    Alternatives
    • We can have the same server handling the normal web traffic and the websocket traffic using a simple middleware. Here is how.
    • As of rails 5 beta2, the action cable server can now also be side-mounted along with your main rails app. Having two different servers can still make sense: you can scale them individually.

    hth

    更多推荐

    在使用Action Cable时将Ruby on Rails应用程序部署到Heroku(Puma端口侦听)

    本文发布于:2023-08-07 15:00:22,感谢您对本站的认可!
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:时将   端口   应用程序   Cable   Action

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!