はじめに
Maple Yard の来場者は、少数の写真プレビューか、写真ブースの完全なアルバムを必要としています。写真サーバーはすでに動作していますが、来場者に IP アドレスとポートを印刷した紙を渡す必要はないはずです。2 つの名前付きサービスを公開し、クライアントから発見して対応する画像コレクションを保存します。案内所の機能は維持します。
IPv4 アドレス、ホスト名、ポート、パス、ターミナルの役割を識別でき、完全な HTTP ダウンロードコマンドに従った経験が必要です。先にイベントネットワークのプロジェクトを学ぶことをおすすめします。DNS 管理、XML、プログラミングの経験は不要です。推定 60 分には読解と通常の間違いへの対応を含みます。これは作者の見積もりであり、初心者による実測時間ではありません。
Publisher、Client、New Client は、準備された 1 つの LAN 上の隔離された Linux ネットワークノードで、同じカーネルを共有します。Photo Shelf はダウンロードしたファイルを表示します。このラボはローカルリンクの mDNS と DNS-SD を扱います。公開 DNS、ルーターを越える発見、自動的な認可、すべての実機やブラウザーとの互換性は扱いません。見本画像はオリジナルの合成イラストカードであり、実際の来場者の写真ではありません。
動作しているサービスを発見する
このステップでは、何かを公開する前に、正常に動く案内所を利用します。Client から始めます。ターミナルは /home/labex/project/photo-network/client で開始します。このディレクトリとシェルは、他のタブとは独立しています。pwd は現在のディレクトリを表示します。
pwd
マルチキャスト DNS(mDNS)は、隣接する機器が同じローカルリンク上で名前の情報を交換する仕組みです。ここでは IPv4 マルチキャストアドレス 224.0.0.251 と UDP ポート 5353 を使います。.local はこのローカル発見の仕組みに属する接尾辞です。プラットフォームの hosts ファイルに追加したり、公開 DNS ゾーンとして扱ったりしないでください。
DNS ベースのサービス発見(DNS-SD)は、名前の付いたサービスインスタンスを記述します。サービスタイプは、クライアントが探すサービスを表します。_http._tcp は TCP 上の HTTP を意味します。Information Desk のようなインスタンス名は、提供される 1 つのサービスを識別します。接続先ホスト名は、それを提供するノードを識別します。ポートは待ち受け中のアプリケーションを選び、path メタデータはその中のリソースを選びます。名前を見つけることは利用の始まりにすぎません。
avahi-browse は、ネイティブの Avahi デーモンにサービス発見を依頼します。-r は各インスタンスを接続情報に解決し、-t は検索完了後に終了し、-p はセミコロンで区切ったフィールドを出力します。-k は、読みやすい翻訳名ではなく元のサービスタイプ名を保持します。
avahi-browse -rtpk _http._tcp
= で始まり、次のフィールドを含む解決済みの行が表示されます。
=;eth0;IPv4;Information\032Desk;_http._tcp;local;desk.local;10.93.0.10;8080;"path=/welcome/index.json"
新しく見つかったインスタンスには + の行も出力される場合があります。解析用出力の \032 は空白を表します。解決済みの行を、インスタンス、タイプ、ドメイン、接続先ホスト名、アドレス、ポート、TXT メタデータの順に読んでください。行の順序やエスケープ表現は変わる場合があります。ネイティブデーモンは、この LAN 経由でこれらのレコードを受信しています。用意済みの発見リストはありません。
提供されている photo-get クライアントで、インスタンス名を指定してコレクションを保存します。引用符は、空白を含む名前を 1 つの引数として扱います。2 番目の引数は、このターミナルの作業領域内の出力フォルダーです。
photo-get "Information Desk" desk
photo-get は再び本物の Avahi 検索を行い、その正確なインスタンスを解決して接続先を表示します。広告された JSON インデックスと、そこに並ぶ各 PNG を取得し、すべての画像をデコードしてから、受信したバイトを保存します。IP、ポート、パスをステーション計画から読み取ることはありません。インデックスには画像ファイル名が並んでいます。これはこのアプリケーションの約束であり、汎用 DNS-SD 形式ではありません。Saved 1 real images と表示され、desk フォルダーに保存されます。
Photo Shelf に切り替え、Client を選択して保存ファイルを再読み込みします。Welcome to Maple Yard カードが表示されるはずです。ビューアーはこのクライアントの作業領域に保存されたファイルだけを読みます。サーバーから取得したり、欠けた画像を補ったりしません。Download image リンクは同じ保存済みファイルを返します。

Client の選択は、この作業領域を示します。案内所のカードは、写真ブースを追加するときも維持する正常な見本です。
検索結果が空の場合は、正確なサービスタイプと、現在 Client にいることを確認してから再検索します。Daemon not running は、発見クライアントが準備されたデーモンに接続できないことを示し、空の結果とは異なります。photo-get が名前を解決できない場合は、綴りと引用符を解決済みの行と比較します。接続拒否はアドレスが見つかったものの、そのポートで接続を受け入れるものがない状態です。HTTP 404 はサーバーには到達したがリソースパスが存在しない状態です。JSON や画像のデコードエラーは、返された内容が不適切であることを示します。hosts エントリーや手作業でコピーした画像で、これらの問題の解決を置き換えないでください。
完全なテンプレートからブースを公開する
このステップでは、既存のプレビューサーバーを広告します。Publisher に切り替えます。ターミナルの開始ディレクトリは /home/labex/project/photo-network/services です。cat はテキストファイルを表示し、../ は親ディレクトリを表します。
cat ../stations.tsv
この業務計画は、準備済みの実際の待ち受けサービスを示しています。Photo Booth Preview は publisher.local にあり、ポートは 8081、リソースは /preview/index.json です。完全なアルバムは、別の待ち受けサービスとリソースです。案内所は別ノードにあり、変更せず維持します。
未完成のプレビュー定義を読みます。
cat preview.service
ここでの .service ファイルは XML を使用します。開始タグと終了タグが各値を囲みます。service-group には表示用の name が入り、その service が type、port、txt-record を指定します。定義を公開しても、ウェブサーバー、コレクション、アクセス権限は作成されません。それらのアプリケーションはすでに動いています。
次の here-document は、小さなファイル全体を書き込みます。> は以前の内容を置き換えます。引用符付きの 'XML' は本文を文字どおりに保持します。最後の XML は行頭に単独で置く必要があります。ブロック全体をコピーしてください。
cat > preview.service <<'XML'
<?xml version="1.0" standalone="no"?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name>Photo Booth Preview</name>
<service>
<type>_http._tcp</type>
<port>8081</port>
<txt-record>path=/preview/index.json</txt-record>
</service>
</service-group>
XML
保存した定義を読みます。
cat preview.service
コースの photo-load コマンドは、編集可能な両方の XML ファイルを解析してから、Publisher の Avahi デーモンだけに再読み込みを依頼します。案内所や業務サーバーは再起動しません。
photo-load
Reload requested for the photo publisher が表示されます。名前の競合確認と登録のため、数秒待ってください。解析成功は XML の構造を確認するものであり、広告されたポートやパスが正しい証拠ではありません。終了タグが欠けると、photo-load はファイル名と解析エラーを報告し、再読み込み要求を送りません。ファイルを読み、完全なブロックに戻して photo-load を再実行します。環境をリセットする必要はありません。
Client に切り替えて再検索します。
avahi-browse -rtpk _http._tcp
Photo Booth Preview と、その接続先 publisher.local、ポート 8081、/preview/index.json を確認します。実際のコレクションを保存し、デコードします。
photo-get "Photo Booth Preview" preview
プレビュー画像が 1 枚得られます。Photo Shelf で Client を選び、再読み込みして、既存の案内所カードとプレビューカードを見比べてください。一覧にサービスが表示されても、正しい画像を取得できなければ未完成です。
2 つのサービスを見分ける
このステップでは、同じノード上で完全なアルバムを公開し、2 つのインスタンスを見分けます。Publisher に切り替えます。両方とも _http._tcp と publisher.local を使いますが、アルバムはポート 8082 と /album/index.json を使います。3 枚の画像があり、1 枚だけのプレビューとは異なります。
すでに学んだ here-document 構文で、別の定義を書き込みます。
cat > album.service <<'XML'
<?xml version="1.0" standalone="no"?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name>Photo Booth Full Album</name>
<service>
<type>_http._tcp</type>
<port>8082</port>
<txt-record>path=/album/index.json</txt-record>
</service>
</service-group>
XML
photo-load
Client に切り替えます。検索し、各解決済み行を別々に読みます。
avahi-browse -rtpk _http._tcp
2 つのインスタンス名は異なるはずです。ホスト名が共通でも、ポートやリソースが同じとは限りません。プレビューを残し、アルバムを専用のフォルダーへダウンロードします。
photo-get "Photo Booth Full Album" album
3 枚の PNG がデコードされ、Saved 3 real images と表示されます。Photo Shelf で Client を選択して再読み込みします。アルバムとプレビューが、それぞれ独自の保存済みファイルを表示するはずです。
次に、正しいコレクションを編集したり削除したりせず、間違ったリソースを見分ける練習をします。意図的に存在しないインスタンス名を使い、ダウンロード前に失敗させます。
photo-get "Photo Booth Missing" missing
Download stopped: Expected one resolved instance と表示され、ゼロ以外の終了状態になります。これは意図した失敗です。実際に解決されたアルバム名を再び使用して復旧します。
photo-get "Photo Booth Full Album" album
間違ったポートやパスを広告した場合、そのインスタンスの解決済み行を stations.tsv と比較します。Publisher で対応する .service ファイルだけを、提示された完全なブロックで修正し、photo-load を実行します。その後 Client で検索とダウンロードを再実行します。待ち受けポートが違えば接続が拒否される場合があり、パスが違えば HTTP 404 になる場合があります。到達できる別のコレクションは正常にデコードできても、業務上は間違った結果です。終了状態がゼロであることだけでなく、コレクションのタイトルとファイル名を確認してください。
Avahi は変更や取り消しを通知します。更新が伝わるまで、クライアントが古いレコードを短時間保持することがあります。読み込み後に数秒待ち、再検索してください。コピーしておいた古い接続先を使い続けないでください。次のステップでは独立したクライアントデーモンと作業領域から確認します。
別のクライアントから結果を利用する
このステップでは、別のネットワーク識別情報と、独立した Avahi デーモンを使用します。New Client に切り替えます。開始ディレクトリは /home/labex/project/photo-network/new-client です。最初のクライアントのシェル変数や保存済みコレクションは、初期状態では共有しません。タブを開いても、公開ノードがリセットされたり広告が作成されたりはしません。
最初のクライアントの行をコピーせず、このクライアントから検索します。
avahi-browse -rtpk _http._tcp
解決された 3 つのインスタンスの対応関係を読みます。プレビューと完全なアルバムは接続先が同じで、ポートとパスが異なります。案内所には独自の接続先があります。このクライアントから 3 つすべてをダウンロードします。
photo-get "Photo Booth Preview" preview
photo-get "Photo Booth Full Album" album
photo-get "Information Desk" desk
プレビュー 1 枚、アルバム画像 3 枚、案内所カード 1 枚が得られます。各呼び出しは、名前付きインスタンスを再び解決し、実際に使用した接続先を表示します。これらのコマンドは静的 IP による発見を設定しません。
Photo Shelf に切り替え、New Client を選択して再読み込みします。すべての画像とコレクションのタイトルを確認します。保存済み画像カードの Download image を選び、ダウンロードした画像が表示中の保存済みカードと一致することを確認します。ビューアーは最初のクライアントの成果を無断でコピーしたり、欠けたファイルを補充したりしません。Client と New Client を切り替え、それぞれ別のコレクションを見てください。

New Client の選択、3 枚のアルバムカード、案内所カード、独立したプレビューカードを確認します。各 Download image リンクは、実際に保存されたファイルに対応します。
コレクションが足りなければ New Client に戻り、現在の広告を確認してからそのダウンロードを繰り返します。保存済み PNG が欠けていたり読めなかったりすると、ビューアーは置き換えるのではなく報告します。まず公開情報や接続を直し、photo-get を再実行して完全な元のコレクションを取得します。完全なインデックスとすべての画像を取得してデコードした後にだけ、ダウンロードは成功になります。
これで、サービス公開と利用を結び付けました。区別できる 3 つのインスタンス、正しい現在の接続先、2 つのクライアント上の実ファイル、そして利用可能な案内所があります。発見は接続情報を提供するものであり、認証や、見つかったサービスの信頼性を保証するものではありません。
まとめ
ネイティブの mDNS/DNS-SD レコードを検索し、インスタンス名とホスト名を区別して、別々のポートとパスメタデータを持つ 2 つの HTTP サービスを公開しました。それぞれの実際の発見結果からデコード可能な画像をダウンロードし、独立したクライアントで同じ流れを繰り返し、案内所を利用可能に保ちました。発見の行と接続成功は異なる証拠です。正しい内容を保存することで、成果が完成します。



