JavaScript/BroadcastChannel
BroadcastChannelオブジェクト
はじめに
BroadcastChannel
オブジェクトは、同一オリジン内の複数のブラウジングコンテキスト(ウィンドウ、タブ、フレーム、iframeなど)間でメッセージをブロードキャストするための仕組みを提供します。これにより、同じWebアプリケーションの異なるインスタンス間でシームレスな通信が可能になります。
基本的な使用方法
BroadcastChannel
は、特定の名前を持つチャネルを作成し、そのチャネルを通じてメッセージを送受信します。同じ名前のチャネルに接続している全てのコンテキストがメッセージを受信できます。
以下は基本的な使用例です:
// チャネルを作成する const channel = new BroadcastChannel('app_channel'); // メッセージを送信する channel.postMessage({ type: 'notification', content: 'データが更新されました' }); // メッセージを受信する channel.onmessage = (event) => { console.log('受信したメッセージ:', event.data); }; // チャネルを閉じる(使用終了時) channel.close();
イベントハンドリング
BroadcastChannel
は以下のイベントを処理します:
イベント名 | 説明 |
---|---|
message | メッセージを受信した時に発火します |
messageerror | 受信したメッセージをデシリアライズできなかった時に発火します |
// messageイベントリスナーを追加 channel.addEventListener('message', (event) => { console.log('メッセージ受信:', event.data); }); // messageerrorイベントリスナーを追加 channel.addEventListener('messageerror', (event) => { console.error('メッセージエラー:', event); });
実用的な例:タブ間同期
BroadcastChannel
の一般的なユースケースは、複数のタブ間でアプリケーションの状態を同期させることです。以下は、ユーザーのログイン状態を同期する例です:
const authChannel = new BroadcastChannel('auth_status'); // ログイン処理 function login(username, password) { // ログイン処理の実装 // ... // ログイン成功後、他のタブに通知 authChannel.postMessage({ action: 'login', user: { username: username, role: 'user' } }); } // ログアウト処理 function logout() { // ログアウト処理の実装 // ... // ログアウト後、他のタブに通知 authChannel.postMessage({ action: 'logout' }); } // メッセージを受信して処理 authChannel.onmessage = (event) => { const data = event.data; if (data.action === 'login') { // UI更新: ログイン状態を反映 updateUIForLoggedInUser(data.user); } else if (data.action === 'logout') { // UI更新: ログアウト状態を反映 updateUIForLoggedOutUser(); } };
送信可能なデータ型
BroadcastChannel
で送信できるデータ型は、構造化クローンアルゴリズムによってシリアライズ可能なものに限られます。
データ型 | 送信可能 | 備考 |
---|---|---|
プリミティブ型(数値、文字列、真偽値など) | ✓ | |
オブジェクト、配列 | ✓ | 循環参照を含まないもの |
Map , Set |
✓ | |
Date |
✓ | |
Blob , File , FileList |
✓ | |
ArrayBuffer , TypedArray |
✓ | |
関数 | × | シリアライズ不可 |
DOM要素 | × | シリアライズ不可 |
Error |
△ | 一部のプロパティのみ |
複数チャネルの管理
大規模なアプリケーションでは、複数のBroadcastChannel
を使い分けることで、メッセージの種類ごとに異なるチャネルを設定できます:
// アプリケーションの異なる機能に対応する複数のチャネル const stateChannel = new BroadcastChannel('app_state'); const notificationChannel = new BroadcastChannel('notifications'); const themeChannel = new BroadcastChannel('theme_settings'); // テーマ変更を他のタブに通知 function changeTheme(themeName) { document.body.className = themeName; // 他のタブにテーマ変更を通知 themeChannel.postMessage({ theme: themeName }); } // テーマの同期を受信 themeChannel.onmessage = (event) => { document.body.className = event.data.theme; }; // アプリケーションの終了時にはすべてのチャネルを閉じる function cleanup() { stateChannel.close(); notificationChannel.close(); themeChannel.close(); } // ウィンドウが閉じる際にクリーンアップ window.addEventListener('beforeunload', cleanup);
ブラウザの互換性と制限事項
BroadcastChannel
は現代的なブラウザでサポートされていますが、IE (Internet Explorer)ではサポートされていません。また以下の制限事項があります:
- 同一オリジン内のみで機能します(セキュリティのため)
- サードパーティCookieの制限により、iframe間の通信に影響する場合があります
- シリアライズ不可能なデータは送信できません
ブラウザ間の互換性を確保するには、以下のようにfeature検出を行うとよいでしょう:
if ('BroadcastChannel' in window) { // BroadcastChannelが利用可能 const channel = new BroadcastChannel('app_channel'); // ... } else { // 代替手段(例:localStorage + storageイベント)を使用 console.warn('BroadcastChannelはサポートされていません。代替手段を使用します。'); // ... }
まとめ
BroadcastChannel
オブジェクトは、単一のWebアプリケーションの複数インスタンス間でのリアルタイム通信を簡単に実現する強力なAPIです。タブ間の状態同期、通知の共有、設定の反映などのユースケースに最適です。シンプルなAPIと効率的な通信メカニズムにより、複雑なマルチタブアプリケーションの開発が容易になります。