【Rails】リアルタイムチャット機能実装（Action Cable）3/3

# 目的
Railsで作成したアプリに、`Action Cable`を用いてリアルタイムチャット機能を導入する。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提

- `Action Cable`の実装が完了している。
[【Rails】リアルタイムチャット機能実装（Action Cable）2/3](https://qiita.com/oak1331/items/7c2d41f3d2e2f06925ce)
- `Heroku`または`AWS`でのデプロイが完了している。
[【Rails】Herokuでアプリをデプロイする方法](https://qiita.com/oak1331/items/4aaf30ecdd5caa827268)
[【AWS】EC2でのデプロイ（EC2の初期設定）](https://qiita.com/oak1331/items/cb435733a04a63fce94e)

# 手順

1. [はじめに](#はじめに)
1. [HerokuとAWSで必要な設定](#herokuとawsで必要な設定)
1. [Herokuで必要な設定](#herokuで必要な設定)
1. [AWSで必要な設定](#awsで必要な設定)

# はじめに

今回は、`ActionCable`を用いて実装したアプリを、本番環境で使用するための設定を行っていきます。
`Heroku`や`AWS`でデプロイした場合を想定しています。

# HerokuとAWSで必要な設定

それでは早速始めていきます！
まず`Heroku`でも`AWS`でも必要な設定をするために`config/cable.yml`を編集します。

`cable.yml`とは`ActionCable`を使用する際の設定を記述するファイルです。
ここでは、使用する`adapter`の指定を変更し、本番環境の仕様設定に編集を加えます。

`ActionCable`は、サーバーから送信された情報をクライアントへ提供する仕組みがあって成り立っており、その仕組みと連携するためのものを`adapter`と言い、使用できる`adapter`の種類には、以下の3通りがあります。

|  種類               |  備考                                                                                |
| ------------------ | ------------------------------------------------------------------------------------ |
|  Asyncアダプタ       |  パフォーマンスの面から本番環境での利用は非推奨（個人アプリの規模であれば、基本的に挙動に問題はない）       |
|  Redisアダプタ       |  本番環境での利用が推奨されている。一方で、EC2を用いたデプロイを行う際に、幾らか料金がかかる              |
|  PostgreSQLアダプタ  |  本番環境での利用が推奨されている。一方で、データベースとのやりとりには、PostgreSQLを使用していることが条件  |

今回は無料で利用できる`Asyncアダプタ`を使用します！

```ruby:config/cable.yml
development:
  adapter: async
test:
  adapter: test
production:
  adapter: async # 追記
  # adapter: redis 削除
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: mini_talk_app_production
```

これで、`cable.yml`の編集は完了です!

# Herokuで必要な設定

次に、Herokuを用いてデプロイする場合にのみ必要な設定をしていきます！
設定を行うファイルは、`config/environments/production.rb`です。

`ActionCable`は、指定されていないオリジンからのリクエストを受け付けない設定がなされているため、本番環境で`ActionCable`を使用できるように設定を編集します！

```ruby:config/environments/production.rb
Rails.application.configure do # このブロックの中であればどこに記載しても良い

#省略

  ActionCable.server.config.disable_request_forgery_protection = true
  config.action_cable.url = "wss://【Herokuアプリ名】.herokuapp.com/cable" 
  config.action_cable.allowed_request_origins = ['https://【Herokuアプリ名】.herokuapp.com', 'http://【Herokuアプリ名】.herokuapp.com']

#省略

end
```

これで、Herokuを用いてデプロイする場合の設定は完了です!

# AWSで必要な設定

最後に、AWSを用いてデプロイをする場合の設定を行います！

設定を行う箇所は、以下の2箇所です。
`config/environments/production.rb`
`Nginxの設定（/etc/nginx/conf.d/rails.conf）`

まずは、本番環境の設定ファイルである`config/environments/production.rb`を編集します。

```ruby:config/environments/production.rb
Rails.application.configure do # このブロックの中であればどこに記載しても良い

#省略

  ActionCable.server.config.disable_request_forgery_protection = true
  config.action_cable.url = "ws://【Elastic IP】/cable" 
  config.action_cable.allowed_request_origins = ['http://【Elastic IP】']

#省略

end
```

続いて`Nginxの設定（/etc/nginx/conf.d/rails.conf）`です。
`ActionCable`を用いる場合、サーバーサイドへのリクエストを受け取る役目のあるWebサーバーにて、`websocket`の仕組みを用いるための設定をする必要があるため、Nginxの設定ファイルにあたる`rails.conf`を編集します。
まず下記コマンドで、`rails.conf`を開いてください！

```:ターミナル(EC2内で実行)
sudo vim /etc/nginx/conf.d/rails.conf
```

開けたら、下記のコードを追記します。
追記するためには`「i」`を押して、インサートモードにする必要があります。

```ruby:/etc/nginx/conf.d/rails.conf
upstream app_server {
  server unix:/var/www/アプリ名/shared/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name Elastic IP;

  root /var/www/アプリ名/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    root   /var/www/アプリ名/current/public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }
# -------------------ここから-------------------
# /cableのパスに対してwebsocketの仕組みを用いるための設定
  location /cable {
    proxy_pass http://app_server/cable;
    proxy_http_version 1.1;
    proxy_set_header Upgrade websocket;
    proxy_set_header Connection Upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
# -------------------ここまでを追記-------------------
  error_page 500 502 503 504 /500.html;
}
```

追記ができたら`「esc」`、`「:wq」`で保存します。

保存が完了したら下記のコマンドにて、Nginxの設定ファイルの読み込み直しとNginxの再起動を行います。

```:ターミナル(EC2内で実行)
sudo systemctl reload nginx
```

```:ターミナル(EC2内で実行)
sudo systemctl restart nginx
```

本番環境にて、ローカル環境と同様の挙動が確認できれば設定完了です。

# 最後に

以上で、`Action Cable`を本番環境での実装は完了です。
では。