新しい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.ymlのdefaultアンカーでコケることがありました。これはとっくに各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
これで大体のセットアップは終わったので、次はようやくユーザーモデルの導入かと思います。