Rails · · Sampo Kuokkanen

新しいRails 8アプリ作成したら、WebSocketを賢く使おう!(Solid Cable / AnyCable)

ActionCableからSolid Cable、そしてAnyCableへ

まず、RailsはデフォルトでActionCableというものが入っていて、 それでWebSocketが使えて、チャンネルなど、インタラクティブな要素にもってこいです。

Rails 8ではSolid Cableがデフォルト

Rails 8からは、ActionCableのアダプターがDBベースのSolid Cableになりました。 以前はプロダクションでActionCableを使うならRedisが必須でしたが、Solid Cableなら アプリのDB(SQLite/PostgreSQL)をそのまま使うので、Redisを別で立てなくても本番で動きます。 小〜中規模ならまずはこれで十分です。

ActionCableの問題点(大規模になると)

Rubyという言語は同時処理には弱い言語ではあります。最近よくなっている分野でも ありますが、Go、Elixirなどと比べると劣るところはあります。 その代わり、書きやすい・読みやすい言語でもあるので、開発スピードの速さは魅力的です。

なので、大量の同時接続をさばきたい場合は、Rubyはそのまま使って、WebSocketという負荷が高いところだけ AnyCableにして、Goベースのサーバーに任せる、というのが一番いいです。

# Gemfile
gem "anycable-rails"

というGemをGemfileに追加しましょう。

bundle exec rails g anycable:setupでAnyCableの設定をやります。

👋 Welcome to AnyCable interactive installer.
    conflict  config/cable.yml
Overwrite config/cable.yml? (enter "h" for help) [Ynaqdhm]

というメッセージが出たら、yを入力します。

設定が進んで、次は

Which environment do you use for development? (1) Local, (2) Docker, (0) Skip

という質問がでます。まだDocker化を今回していないので、1を入力します。

How do you want to install AnyCable-Go WebSocket server? (1) Homebrew, (2) Download binary, (0) Skip

AnyCable-Goのインストール方法ですね。Macであれば1(Homebrew)、Linuxであれば2(バイナリ)を選ぶのが楽です。

補足(2022年当時のハマりどころ):昔はRuby 3.1のPsych 4でYAMLのエイリアスが読めず、 anycable.ymldefaultアンカーでコケることがありました。これはとっくに各Gem側で対応済みなので、 今のanycable-railsでは気にしなくて大丈夫です。

AnyCable-Goのサーバーは以下のコマンドで起動します。

anycable-go --host=localhost --port=8080

これで設定ができました! Procfile.devに足して、全部Railsと一緒に起動されるようにしておくと便利です。

Homebrew以外(バイナリやGo)で入れた場合、パスが通っていないと起動しないことがあるので、 ~/.bashrc(zshなら~/.zshrc)にパスを追加しておきましょう。

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

これで大体のセットアップは終わったので、次はようやくユーザーモデルの導入かと思います。