やってみよう!Phoenix Live View その①
          Phoenix Live Viewを始めよう
LiveView プロセス、エントリーポイント、関数コンポーネントなどの基礎的な概念に親しんで行きましょう。
本章では次のような仕様を追加します。
- 画面の上部に「Home」と「Robot」という 2 つのリンクが表示される。
 - ユーザーが「Robot」をクリックすると、枠線の中に「Robot」と表示される。
 
シングルページアプリケーション(SPA)とは?
伝統的なウェブアプリケーションでは、繰り返し新たなページをロードすることで様々な機能が実現されています。それに対して、シングルページアプリケーションでは最初にロードされたページを JavaScript の力を借りて次々と書き換えていきます。
JavaScript によるページの書き換えは新たなページをロードするよりも時間がかからないので、シングルページアプリケーションはネイティブアプリケーションのようなユーザー体験を提供します。
AjaxとWebSocket
シングルページアプリケーションを実現するための主な技術要素は、次の 2 つです:
- Ajax(エイジャックス)
 - WebSocket(ウェブソケット)
 
Ajax は、JavaScript の組み込みクラスである XMLHttpRequest を利用して、ブラウザからサーバーに対して HTTP リクエストを送ってデータを取得することにより、ページを動的に書き換えるという開発手法です。
WebSocket は、ブラウザとサーバーの間で双方向通信を実現するための通信プロトコルです。サーバー側からブラウザにデータをプッシュ配信することが難しいという Ajax の欠点を解決するための技術として開発されました。
Phoenix LIve View
Phoenix LiveView は WebSocket を利用してシングルページアプリケーションを開発するためのライブラリです。Phoenix とは独立したライブラリですが、--no-liveview オプションを付けずに mix phx.new コマンドを実行すると Phoenix LiveView が Phoenix アプリケーションに組み込まれます。
LiveViewモジュール
RobotLiveモジュールを作る
コントローラのためのモジュールの場合は、HomeController のように「Controller」で終わる名前のモジュールを作りましたが、Phoenix LiveView のためのモジュールの場合は、「Live」で終わる名前とするのが慣習です。この種のモジュールを LiveView モジュールと呼びます。
モジュールのソースコードを置くためのディレクトリを作ってください。
mkdir -p lib/phx_sample_web/liveそして、その下に新規ファイル robot_live.ex を作り、次のコードを書き入れてください。
defmodule PhxSampleWeb.RobotLive do
  use PhxSampleWeb, :live_view
end
LiveView モジュールの場合は、use PhxSampleWeb, :live_view のように書きます。
メインテンプレートを作る
次に、同じディレクトリに robot_live.html.heex を次の内容で作ってください。
<div>Robot</div>RobotLive モジュールのメインテンプレートとして使われます。最初は単に「Robot」と表示するだけとします。
ルーティング設定の変更
ルーティング設定を次のように変更します。
scope "/", PhxSampleWeb do
   pipe_through :browser
   get "/", HomeController, :index
   get "/", HomeController, :hello
   get "/hello/:name", HomeController, :hello
  live "/robot", RobotLive
 end
endこの結果、ブラウザで /robot パスにアクセスしたときに RobotLive モジュールが応答します。
ナビゲーションバーの設置
app レイアウトapp.html.heexの上部にナビゲーションバーを設置しましょう。
<header class="flex justify-center">
  <a href={~p(/)} class="link mx-2">Home</a>
  <a href={~p(/robot)} class="link mx-2">Robot</a>
</header>
<main class="px-4 py-20 sm:px-6 lg:px-8">
  <div class="mx-auto max-w-2xl sm:border-4 sm:border-base-content sm:p-4">
    <.flash_group flash={@flash} />
    {@inner_content}
  </div>
</main>まだ機能を何も追加していないので見た目からはわかりませんが、シングルページアプリケーションとして機能し始めており、ブラウザと Phoenix サーバーの間は WebSocket で接続しています。
WebSocket通信の状態を確認する方法
本当に WebSocket 通信が成立しているかどうかは、ブラウザの DevTools を使って確認できます。Chrome の場合は、ページ内を右クリックしてコンテキストメニューを開き、「検証」を選択すると DevTools が開きます。
「Network」タブを選択し、「All」、「Fetch/XHR」などのボタンが並ぶ中から「Socket」ボタンをクリックし、ブラウザの画面をリロードすると DevTools には次のように表示されます。

画面下半分の表に websocket? で始まる行が 2 つありますね。これらの行が存在すれば、WebSocket 通信が成立しています。
2 つの行のうち websocket?_csrf_token= で始まっている方を選択してください。すると次のような表示に変化します。

上向きの矢印がブラウザからサーバーに向けての通信、下向きの矢印がサーバからブラウザ向きの通信を示します。「Len...」の列には送信されたデータのサイズ(単位:バイト)が書かれています。最初にブラウザから 863 バイトのデータが送られ、サーバーから 8841 バイトのデータが返ってきていることがわかります。
「Time」列には通信が行われた時刻が書かれています。ここを見ると、30秒ごとにブラウザとサーバーの間でごく小さなデータのやり取りが発生していることがわかります。このときにブラウザからサーバーに送られるデータをハートビートと呼びます。これが途絶えると、サーバー側は WebSocket 通信が切断されたと判断します。