放送チャンネルAPIの調査


あなたはこれらのデジタルメニューボードを知っているクイックサービスのレストランでは?さて、去年私はそれらのうちの1つで働きました.

Ok, but what does that have to do with the Broadcast Channel API?


少しの背景


我々の特定のケースでは、メニューボードは、レストランでクロムメートで実行している反応ウェブアプリです.これは2つのディスプレイをサポートし、我々はURLルートに基づいて表示メニューのどのページを制御します.

要件の1つは、メニューの特定の要素をアニメーション化する必要があったが、キャッチがあった.アニメーションは、ディスプレイ間で同期する必要がありました.我々は、必要に応じてちょうどアニメーションループを発射することができませんでした.我々は、2つのページが同時に彼らのタイマーを始めるために互いに通信する方法を必要としました.
エンターBroadcast Channel API .

放送チャンネルAPIは何ですか?


それは、同じ起源のブラウジング文脈(すなわちWindows、タブ、iframe、webview)の間の基本的なコミュニケーションを許すウェブAPIです.

を作成して起動するBroadcastChannel オブジェクトと名前を与える.同じ名前のチャンネルが既に存在するならば、それは代わりにチャンネルに加わります.
const channel = new BroadcastChannel("channel_name")
メッセージを送信するにはpostMessage() 作成されたオブジェクトのメソッドです.
channel.postMessage("is this thing on?")
これはmessage チャネルに参加したコンテキストの各イベント.このイベントの関数をonmessage イベントハンドラ.
channel.onmessage = ev => {
  console.log(ev.data)
}
// is this thing on?
チャンネルから切断するにはclose() オブジェクトのメソッド.
channel.close()

我々のアプリに戻る


我々は、2つのディスプレイ間で前後に通信し、正確に同時に彼らのアニメーションループを開始することを確認するには、このAPIを活用することができた.それぞれのディスプレイが少しずつ異なって独立して起動することを心に留めておいてください.ですから、両方とも準備ができているときには、前に交渉をする必要があります.
基本的な論理は次のようになります.
/**
 * In this example I will refer to the first display to finish 
 * booting up as "display 1". The second one to be ready will
 * be "display 2".
 */

// display 1 creates the channel; display 2 joins it
const syncChannel = new BroadcastChannel("animation-sync")

syncChannel.onmessage = ({ data }) => {
  switch (data.type) {
    // display 1 receives the "READY" message from display 2
    // and posts a message to start setting things up
    case "READY": {
      syncChannel.postMessage({ type: "START" })
      break
    }
    // display 2 receives the "START" message
    case "START": {
      // record the current time (just to be safe we pad it 5s
      // to allow display 1 to receive the next message)
      const syncTime = new Date().getTime() + 5000

      // outside function that schedules the animations
      scheduleAnimations(syncTime)

      // send "SYNC" message to display 1 with the syncTime      
      syncChannel.postMessage({ type: "SYNC", syncTime })
      break
    }
    // display 1 receives the "SYNC" message with the syncTime
    case "SYNC": {
      scheduleAnimations(data.syncTime)
      break
    }
    default:
      break
  }
}

// display 2 sends the "READY" message to display 1
animationSyncChannel.postMessage({ type: "READY" })

それで遊ぶ


私の作ったa simplified demo of this で使用できます.その短いプレビューを以下に示します.

かなりクール、右?

警告


すべてのブラウザがこれをネイティブにサポートしているわけではない.幸いにも、NPMパッケージと呼ばれるパッケージがありますbroadcast-channel それは同じAPIを持ち、それをサポートするブラウザでネイティブの実装を使用します.さらに、それはあなたもノードでそれを使用することができます!
カバー写真Prince Abid