ActionController::LiveとServer-Sent Events で地図上にじわじわ表示する

Pocket

こんにちは、鈴木です。

 

Rails4 の新機能の一つに ActionController::Live というものがあります。

ActionController::Live はリアルタイムの Push 通知を可能にする機能です。

 

「チャットができるよ。」「またかよ!」

リアルタイム Push 通信を行う他の技術としては、Commet や WebSocket などもあります。

 

これ系の話の応用例として良く挙げられるのはチャットですが・・、そんなにいつもチャットを作るわけではありません。「リアルタイム Push 通信ができる○○登場!チャットができるよ。」→「またかよ!」と思うことも多いです。

 

とはいえ「チャット以外の応用例って何?」と言われてもすぐには良いアイディアが浮かばないのも事実です。「こういう使い方ができるんじゃない?」という思いつきを形にすることを積み重ねていけば、いずれ「これぞ!」という応用が見つかるかもしれません。

 

地図上にマーカーをじわじわ表示するサンプル

ということで、思いつきの一つとして地図上にマーカーをじわじわ表示するサンプルを作りました。

Heroku にサンプルをデプロイしました。以下の URL で確認できるので、良ければ触ってみてください。

jiwajiwa-maps

http://techscore-ac-live-sample.herokuapp.com/

地図をドラッグすると、画面外となったマーカーは削除されるとともに、新しく画面外に入った領域に表示すべきマーカーの情報がじわじわ表示されます。

 

ソースコードは以下の場所にあります。

https://github.com/suzuki-kei/rails4_action_controller_live_with_google_maps_sample

 

ソースコードの解説

Model

地図上に表示するマーカーのテーブルには、「名前」「緯度」「経度」の情報を持たせました。

マイグレーションのコード ( db/migrate/20130907160100_create_markers.rb ) は以下の通りです。

 

Controller

Controller は次のように実装しています。

ポイントは、Content-Type は text/event-stream で返すことと、データを一つずつ response.stream.write で出力しているところです。

「sleep 0.1」を入れているのは、わざと処理を遅くしてマーカーがじわじわ表示されることが分かるようにするためです。

 

View

View はこのようになっています。

Server-Sent Events (EventSource) が使えなければゴメンナサイということで、使える場合は独自に作成した Map オブジェクトが仕事の全てを行います。

 

Javascript

クライアントコードのメインは app/assets/javascripts/map.js に閉じ込めてあります。

100 行弱のコードですが、地図がドラッグされたり倍率が変更されたタイミングで以下の処理を行っています(mapChanged 関数)。

  1. サーバと通信中の場合は、通信をキャンセルする。(cancelRequest)
  2. 地図の範囲外となったマーカーを削除する。(removeOutsideMarkers)
  3. サーバから新しい範囲に含まれるマーカーを取得する。(requestMarkers)

1. はサーバ側に処理が溜まらないようにするため、2. はクライアント側のメモリ使用量が増え続けないようにするために行っています。

また、3 の処理では画面内に既に表示されているマーカーの情報をサーバに送信し、サーバ側は不足分のマーカー情報だけ返せるように工夫しました。

 

まとめ

ActionController::Live の利用例として、またリアルタイム Push 通信活用の一例としてサンプルプログラムを作成しました。

何かの参考になれば幸いです。

 

Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です