概要
こんにちは、QUANON です。
Rails 5 の Action Cable の登場により、Rails アプリケーションの可能性がぐっと広がりましたね。今回はその Action Cable のシンプルな利用例を 1 つご紹介したいと思います。
利用例
サーバ側で何か重い処理を実行しており、その進捗率を逐次ユーザに伝えることができれば便利ですよね。例えば「ユーザから大量データの CSV ファイルの生成リクエストを受け付けて、その生成状況を画面上のプログレスバーにリアルタイムで表示する」などです。クライアントから Ajax 通信でサーバに進捗率を定期的に問い合わせ、その結果を受けてプログレスバーを更新することも可能ですが、できればもっとスマートな方法を選びたいですね。
そこで Action Cable の出番です。WebSocket を使って、サーバからクライアントに直接進捗率を送ってみます。
なお、プログレスバーの HTML はこんな感じです。Bootstrap 4 のプログレスバーを使用しています。
<div class="progress-percentage text-xs-center">0%</div>
<progress class="progress progress-striped" max="100" value="0"></progress>
また Action Cable 自体についての説明やセットアップ方法については省略します。
最初に Channel クラスを作成します。まずサーバ側です。
class ProgressesChannel < ApplicationCable::Channel
def follow(data)
stream_from("progresses:#{data['progress_id'].to_i}")
end
end
次にクライアント側です。
App.progresses = App.cable.subscriptions.create 'ProgressesChannel',
connected: ->
@install()
@follow()
received: (data) ->
$('.progress-percentage').text("#{data.percent}%")
$('progress').prop('value', data.percent)
follow: ->
# 例示のため、購読対象の識別子 (progress_id) は決め打ち
@perform('follow', progress_id: 1)
install: ->
$(document).on('page:change', -> App.progresses.follow())
実装が終わったら Rails サーバを起動します。ここでは Action Cable サーバは Rails サーバに組み込まれていることを想定します (別のサーバとして起動することも可能なため) 。動作確認のため、別途 Rails コンソールも起動します。ここで注意点ですが、開発環境のデフォルトのサブスクリプションアダプタは async
です。これでは同一のプロセスからの broadcast
しか有効になりません。つまり Action Cable サーバと別プロセスである Rails コンソールから broadcast
を実行しても何も起きません。そこで Redis を使うように設定しておきます。
development:
adapter: redis
url: redis://localhost:6379
では Rails コンソールから broadcast
を実行してみます。今回の例では、
ActionCable.server.broadcast('progresses:1', percent: 64)
のようなコードを実行します。
Rails コンソールで実行したコードと画面のプログレスバーが同期しているのが分かります。
実際は ActiveJob を利用して、バックグラウンドジョブの中で broadcast
を実行することになると思います。
感想
Action Cable は様々な場面で役立ちそうですし、なによりリアルタイムに動く様子は実装していて非常に楽しいです。Rails 5 は最高ですね
皆さんも是非 Action Cable をエンジョイしてみてください。