Ruby on rails 使用Action Cable(Puma端口监听)将Ruby on Rails应用程序部署到Heroku
我已经在本地主机环境中使用了Action Cable,在这种情况下,我使用一个包含Ruby on rails 使用Action Cable(Puma端口监听)将Ruby on Rails应用程序部署到Heroku,ruby-on-rails,heroku,puma,actioncable,Ruby On Rails,Heroku,Puma,Actioncable,我已经在本地主机环境中使用了Action Cable,在这种情况下,我使用一个包含 # /bin/bash bundle exec puma -p 28080 cable/config.ru 一旦发生这种情况,puma服务器将启动并侦听此28080端口和本地服务器运行的端口。通过在线搜索,我找不到一个地方可以告诉我如何在heroku上模拟这种情况,或者如何让我的服务器始终在同一个端口上启动(尽管我也不知道这是否会给我期望的结果) 我设置了一个javascript文件来创建与该端口相关的使用者
# /bin/bash
bundle exec puma -p 28080 cable/config.ru
一旦发生这种情况,puma服务器将启动并侦听此28080端口和本地服务器运行的端口。通过在线搜索,我找不到一个地方可以告诉我如何在heroku上模拟这种情况,或者如何让我的服务器始终在同一个端口上启动(尽管我也不知道这是否会给我期望的结果)
我设置了一个javascript文件来创建与该端口相关的使用者
//= require cable
//= 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文件,该文件的端口设置为
... (only part of the file)
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
...
因此,在我看来,ENV['PORT']被定义为当我检查heroku日志时,puma服务器将
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 http://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
如果有任何不清楚之处,我深表歉意,如果我遗漏了任何信息,我将乐意提供更多信息
编辑
下面是/app/assets/javascripts/channels/index.js.erb中的更新代码
//= require cable
//= require_self
//= require_tree .
this.App = {};
App.cable = Cable.createConsumer('<%= ENV["CABLE_SERVER"] %>');
/=需要电缆
//需要自己
//=需要一棵树。
this.App={};
App.cable=cable.createConsumer(“”);
其中ENV[“CABLE_SERVER”]指向ws://action-CABLE-SERVER.herokuapp.com
。此变量存储在rails服务器环境变量中。Issue
Heroku有一些限制:它只监听端口80和443。换句话说,您不能在任何Heroku应用程序上打开固定端口。在ActionCable服务器的情况下,无法打开固定端口并将websocket流量路由到该端口。所以要么Heroku允许这样的事情(我怀疑),要么我们使用一种变通方法
变通办法
从actioncable的0.0.3版开始,以下是我使用的解决方法
这样做的目的不是要有一个Heroku应用程序,而是要有两个:一个用于rails主服务器,一个用于ActionCable服务器。两者都将在端口80(或443)上运行
从一个代码库运行两个不同的服务器只需要有两个procfile:一个用于rails,一个用于action cable。处理这件事是有办法的。要使用它,您还需要
假设您有两个名为rails
和actioncable
的Heroku应用程序
使用以下命令在项目根目录中创建.buildpacks
文件:
https://github.com/cantino/heroku-selectable-procfile
https://github.com/heroku/heroku-buildpack-ruby
在rails
和actioncable
上,使用https://github.com/heroku/heroku-buildpack-multi.git
现在对于Procfiles,我选择保留Procfile
,以便与foreman一起在本地运行所有内容,并创建两个自定义文件:Procfile.rails
和Procfile.actioncable
在Procfile.rails
中,您描述了除action cable服务器之外的所有所需的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
中,您只描述了action cable服务器:
web: bundle exec puma -p $PORT cable/config.ru
请注意,我们使用的是web
dyno,它将在端口80(或443)上安装action cable服务器
小心您需要将puma配置文件config/puma.rb
移动到自定义位置。我选择config/puma/config.rb
config/puma.rb
是在没有任何特定配置文件的情况下启动puma时的默认位置,这是我们在Procfile.actioncable
中提供的。这可能会导致意外行为(请参见下面的注释)
现在,在rails
上,使用PROCFILE.rails
创建一个env varPROCFILE\u路径
,在actioncable
上,使用PROCFILE.actioncable
创建一个env varPROCFILE\u路径
说到环境变量,actioncable
需要来自rails
的所有环境变量,它们是启动actioncable服务器所必需的,如数据库URL或任何凭证
现在关键的一步是:我们如何将rails
和actioncable
连接在一起?这只需使用相同的Redis实例即可完成rails
将把消息放在Redis上,actioncable
将倾听消息并相应地采取行动。这就是为什么两者都必须针对相同的Redis实例。如果您使用Heroku Redis,只需在rails
和actioncable
上使用相同的值设置Redis\u URL
。以下是电缆服务器的配置文件cable.yml
:
production: &production
:url: <%= ENV["REDIS_URL"] %>
:timeout: 1
development: &development
:url: <%= ENV["REDIS_URL"] %>
:timeout: 1
:inline: true
test: *development
这个CABLE\u服务器
变量现在可以在本地和rails
上指向ws://127.0.0.1:28080
,该值将是actioncable
的url
现在,您可以在rails
和actioncable
上部署代码了
注意事项/缺点
- 在
actioncable
上,如果您有任何客户端身份验证,则不能像在中一样使用cookies
。你现在有两个Heroku应用程序,它们不能共享cookie。我想您仍然可以使用多个子域的cookie来实现这一点
- 现在有两个部署目标需要维护
- 您要维护多个proc文件
- 希望随着时间的推移,会有一个更简单的解决办法:)
选择
- 我们可以使用一个简单的中间件让同一台服务器处理正常的web流量和websocket流量。就是这样
- 从Rails5Beta2开始,ActionCable服务器现在也可以与rails主应用程序一起使用。拥有两台不同的服务器仍然是有意义的:您可以单独扩展它们
hth当actioncable启动时,它也会打印在日志中2015-07-31T23:21:18.708169+00:00 heroku[web.1]:使用命令包exec puma启动进程-p 28389 cable/config
//= require cable
//= require_self
//= require_tree .
this.App = {};
App.cable = Cable.createConsumer('<%= ENV["CABLE_SERVER"] %>');