MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Using the Push API

W3CのPush APIは新しい機能をWebアプリケーションを作るデベロッパーのみなさんへ提供します!: この記事はシンプルなデモを使ってプッシュ通知の設定と使い方を紹介します。

サーバからクライアントへメッセージや通知をいつでも(アプリを実行していなくても)送信できる、ネイティブプラットフォームでよく知られた技術がついにWebにやってきました!ほとんどのプッシュ通知がデスクトップの Firefox 43+ とChrome 42+ にサポートされており、モバイル向けにも準備を進めています。PushMessageData は現在 Firefox Nightly (44+) に実験的にサポートされており、現在の開発のメイントピックになっています。

Note: 初期のバージョンの Firefox OS は Simple Push というAPIを使っていましたが、これは Push API standard からは時代遅れになってきています。

Note: デモ中のいくつかのクライアントサイドのコードは Matt Gaunt による素晴らしいサンプルコード Push Notifications on the Open Web から強く影響を受けています。Matt ありがとう!

デモ: シンプルなチャットサーバーアプリ

このデモではシンプルなチャットアプリを作ります。このアプリにはあなたのハンドルネームを入力するフォームとプッシュメッセージを受け取るボタンがあります。一度そのボタンを押したらあなたはプッシュメッセージを受け取ることができます。あなたの情報についてはサーバに保存され、プッシュメッセージはこのボタンを押したすべてのユーザに送信されます。

ここでは、新しくメッセージを受け取るユーザの名前は購読者リストに表示されます。メッセージを入力するテキストフィールドと購読者がメッセージを送信できるボタンも同様に表示されます。

このデモを動かすために、push-api-demo README を読んでください。ここにあるサーバサイドのコンポーネントは合理的に動かしたり、 Chrome で動かすためにはもう少し手を加えなければならないことをあらかじめ指摘しておきます。しかしプッシュ通知を理解するためには全く問題ありません。これについては私たちがこの技術のレビューを終えた後で改善していくつもりです。

テクノロジー

ここではこのデモで使うテクノロジーの概要を説明していきます。

プッシュメッセージは service workers テクノロジーの一部です。service workerはプッシュメッセージを受け取るためにWebページ上でアクティブにされる必要があります。service workerはプッシュメッセージを受け取り、それをどのように通知するのかはあなたの実装次第です。あなたには以下のことができます。

  • Web notification を送り、システム通知をポップアップさせる。これにはプッシュメッセージを送信するためにユーザからの承認が必要になります。
  • MessageChannelを経由してメッセージをメインページに送り返す。

場合によって以上の二つを組み合わせることが必要になります。このデモでは組み合わせることなく、個別に例を紹介します。

Note: エンドポイントやデータ暗号化、プッシュメッセージリクエストを送るためにサーバサイドのプログラムが必要です。このデモではNodeJSを用いた簡単なプログラムを用いています。

service worker はプッシュメッセージサービスからメッセージを受け取る必要があります。そのために、それぞれのセッションには固有のエンドポイントが与えられています。このエンドポイントは購読対象の(PushSubscription.endpoint)プロパティから得ることができます。このエンドポイントはあなたのサーバから送信され、そのセッションでアクティブになっているservice workerへメッセージを送信するのに使用されます。それぞれのブラウザはプッシュメッセージを送信するための固有のプッシュメッセージサーバを持っています。

プッシュメッセージでデータを送るために、データを暗号化する必要があります。これには、複雑な暗号化処理をするサーバサイドプログラムに依存したPushSubscription.getKey()メソッドで作成される公開鍵が必要です。詳しくは Message Encryption for Web Pushを読んでください。時間が経てばプッシュメッセージを暗号化/復号化する公開鍵を生成するライブラリが現れるでしょう。このデモではMarco CastelluccioのNodeJS web-push libraryを使用します。

プッシュワークフロー

プッシュメッセージを実装するために、以下のことが必要です。ここにはGithubにある私たちのデモや、他のチュートリアルがまとめられています。デモの特定の部分の詳細は後のセクションで説明します。

  1. Web通知など、承認が必要なことをユーザに承認(permission for web notifications)してもらうためにリクエストを送る。
  2. ページを捜査するためServiceWorkerContainer.register()を呼んでservice workerを登録(Register a service worker)する。
  3. PushManager.subscribe()を使ってプッシュメッセージサービスを受信(Subscribe to the push messaging service)する。
  4. エンドポイントを講読情報と一緒に受け取り、クライアント公開鍵(PushSubscription.endpoint と PushSubscription.getKey()。* getKey() はβ版でFirefoxのみ)を生成(Retrieve the endpoint associated with the subscription and generate a client public key)する。
  5. これらの情報をサーバへ送る(Send these details to the server)。これで、必要な時にプッシュメッセージを送信できる。ここのデモではXMLHttpRequestを使っているが、Fetchを使うこともできる。
  6. もしservice workerと通信するのに Channel Messaging API を使っているのであれば、new message channel (MessageChannel.MessageChannel()) を設定し、communication channelを開くためにWorker.postMessage()をservice workerで呼ぶことでport2をservice workerに送信(send port2 over to the service worker)する。service workerから送り返されたメッセージに対応するlistnerの設定(set up a listener to respond to messages sent back from the service worker)も行う。
  7. サーバサイドでは、エンドポイントや他に必要な情報を保存(store the endpoint and any other required details)する。これにより、プッシュメッセージが受信者に送られる時にこの情報を即座に使うことができる。デモでは情報を保存するためにシンプルなテキストファイルを使っているが、データベースでもなんでも使える。実際に公開するアプリでは、これらのデータはすべて隠されていて、悪意のあるユーザからエンドポイントを盗まれたりプッシュメッセージ受信者にスパムメッセージが送られないように注意すること。
  8. データなしにプッシュメッセージを送るためには、プッシュメッセージをエンドポイントURLに POSTメソッドで送信する必要がある。データと一緒にプッシュメッセージを送るためには、クライアント公開鍵を含めたデータを暗号化すること。デモではweb-pushという大変便利なモジュールを使用している(使用例: see usage example)。
  9. プッシュメッセージを受信するために、あなたのservice workerでpush event handlerの設定を行う。
    1. もしあなたがchannel messageのメインコンテキストへの返信に反応したい場合(Step 6 参照)、まずはじめに service worker に送信した port2(port2 we sent over to the service worker)コンテキスト(MessagePort)への参照を取得する必要がある。これはonmessageハンドラへ渡したMessageEventオブジェクトで有効である(ServiceWorkerGlobalScope.onmessage)。具体的に言うと、これはports property, index 0で見つけられる。一度これが見つけられると、あなたはMessagePort.postMessage()を使ってport1にメッセージを送り返すことができる(send a message back to port1)。
    2. もしあなたがシステム通知の実行に反応(respond by firing a system notification)したい場合、ServiceWorkerRegistration.showNotification()を呼ぶことで実現できる。私たちのデモでは、ExtendableEvent.waitUntil()メソッドの中でこれを実行している。これはイベントのライフタイムをシステム通知が実行されるまで延長している。これによって実行したかったすべてのイベントが実行されたことを確認できる。

デモの作成

デモを作るためのコードに目を通して、どのようにしてプッシュ通知が動いているのか理解していきましょう。

HTMLとCSS

このデモのHTMLとCSSは特に変わったことはしていません。HTMLは初期状態としてチャットルームに入るためのハンドルネームを入力するシンプルな入力フォームと、プッシュ通知を受け取るボタン、そして購読者リストとメッセージリストの二つのリストがあるだけです。一度プッシュ通知を受け取り始めると、チャットメッセージを入力するフォームが表示されます。

CSSはPush APIの機能を説明するために、本当に最低限のものしかありません。

主要なJavaScriptファイル

このJavaScriptはHTMLやCSSに比べて、本当にたくさんの量があります。このjavaScriptファイルを見てみましょう。

変数と初期設定

まず、いくつかの変数を宣言します。

var isPushEnabled = false;
var useNotifications = false;

var subBtn = document.querySelector('.subscribe');
var sendBtn;
var sendInput;

var controlsBlock = document.querySelector('.controls');
var subscribersList = document.querySelector('.subscribers ul');
var messagesList = document.querySelector('.messages ul');

var nameForm = document.querySelector('#form');
var nameInput = document.querySelector('#name-input');
nameForm.onsubmit = function(e) {
  e.preventDefault()
};
nameInput.value = 'Bob';

はじめに、2つのboolean変数があります。一つはプッシュ通知が受信できる状態か、もう一つは通知がユーザから承認されているか、という状態を管理します。

次に、プッシュ通知を受信しているかどうか参照する<button>と、メッセージ送信ボタンや入力フォームへの参照を保存する変数を定義します。このボタンや入力フォームは、通知の受信準備に成功した時にのみ表示されます。

次の変数はレイアウト内の3つの主要な<div>要素を参照します。これによって、これらの要素内に新しい要素を追加することができます。例えば、メッセージ送信ボタンを表示する時や、チャットメッセージがメッセージリストに表示される時などに新しい要素を追加します。

最後の要素は、名前入力フォームと<input>要素を参照し、これに初期値を与えるよう設定します。Enterキーによるフォーム誤送信を防ぐためにpreventDefault()を実装しています。

次に、requestPermission()を使ってウェブ通知の送信許可をリクエストします。

Notification.requestPermission();

これから、アプリが最初にロードされた時の初期設定を行うため、onloadが実行された時のコードを読み解いていきます。まずはじめにクリックイベントリスナーを受信(subscribe/unsubscribe)ボタンに設定します。このイベントリスナーはisPushEnabledtrueの場合にunsubscribe()関数を実行し、そうでない場合にsubscribe()を実行します。

window.addEventListener('load', function() {   
  subBtn.addEventListener('click', function() {  
    if (isPushEnabled) {  
      unsubscribe();  
    } else {  
      subscribe();  
    }  
  });

次に、service workersがサポートされているのか確認します。もしサポートされているようならServiceWorkerContainer.register()を使ってservice workerを登録し、initialiseState()関数を実行します。サポートされていない場合、エラーメッセージをコンソールに出力します。

  // service workersがサポートされているか確認。サポートされている場合、プッシュメッセージ環境を準備する。サポートされていない場合、準備せずに処理を進める。
  if ('serviceWorker' in navigator) {  
    navigator.serviceWorker.register('sw.js').then(function(reg) {
      if(reg.installing) {
        console.log('Service worker installing');
      } else if(reg.waiting) {
        console.log('Service worker installed');
      } else if(reg.active) {
        console.log('Service worker active');
      }

      initialiseState(reg);
    });  
  } else {  
    console.log('Service workers aren\'t supported in this browser.');  
  }  
});

次にコードの中にあるのはinitialiseState()関数です。英語コメントで説明されているコードを見るには、initialiseState() source on Github を参照してください。Push API自体の説明をするために、この関数の詳細な説明はここでは省略します。

initialiseState()は、はじめに通知がservice workersにサポートされているか確認します。サポートされているようであればuseNotifications変数をtrueにします。次に、ユーザに通知が承認されているか、プッシュメッセージがサポートされているか、それぞれ確認し、それぞれの結果に応じて反応します。

最後に、initialiseState()はservice workerがアクティブになって利用が可能になるまで待機するためにServiceWorkerContainer.ready()を使います。一度この処理が完了したら、ServiceWorkerRegistration.pushManagerプロパティを使ってプッシュメッセージを利用する講読情報を受け取ります。このプロパティはPushManagerオブジェクトを返し、これを使ってPushManager.getSubscription()を呼び出します。これが完了したら、受信(subscribe/unsubscribe)ボタンを有効(subBtn.disabled = false;)にし、私たちが購読オブジェクトを持っていることを確認します。

これができたら、私たちはすでに受信可能状態になっています。これはブラウザ上でアプリが開かれていない場合であっても、です。service workerはバックグラウンドでアクティブになっています。受信可能状態になっていたら、ボタンラベルのUIを更新して受信していることを表示します。そして、isPushEnabled変数にtrueを設定し、購読エンドポイントをPushSubscription.endpointから取得、PushSubscription.getKey()を使って公開鍵を生成し、updateStatus()関数を実行します。この関数はサーバと通信をしています。

おまけとして、私たちはMessageChannel.MessageChannel()コンストラクタを使って、新しいMessageChannelを用意しました。これはServiceworkerRegistration.activeを使ってアクティブなservice workerを取得し、Worker.postMessage()を使ってメインブラウザコンテクストとservice workerコンテクストの間にchannelを用意します。ブラウザコンテクストはMessageChannel.port1でメッセージを受信します。メッセージの受信が行われた時、handleChannelMessage()関数が実行され、受信されたデータを用いてどんな処理をするのか決めます。このデータについてはこちらのセクション(Handling channel messages sent from the service worker)をみてください。

メッセージ受信/受信解除(subscribing and unsubscribing)の設定

プッシュ通知サービスを受信/受信解除するsubscribe()関数とunsubscribe()関数について考えてみましょう。

メッセージを受信する状態のとき、service workerがアクティブで準備ができているかServiceWorkerContainer.ready()を呼び出すことで再度確認します。この処理を完了したら、PushManager.subscribe()を使ってサービスを受信します。メッセージ受信に成功したとき、PushSubscriptionオブジェクトを受け取り、このオブジェクトから購読エンドポイントを取得(PushSubscription.endpoint)し、公開鍵を生成(PushSubscription.getKey())し、必要な情報をサーバへ送るためにエンドポイントと公開鍵をupdate type(subscribe)と一緒にupdateStatus()関数へ渡します。

さらに必要な情報の更新をします。更新するのはアプリの状態とUIです。まずはアプリの状態の更新のため、isPushEnabled変数にtrueを設定します。次に受信(subscribe/unsubscribe)ボタンをアクティブにし、ボタンのラベルテキストを変更します。

unsubscribe()関数はsubscribe() 関数と構造的に似ていますが、基本的に真逆のことをします。特筆すべき相違点は現在の講読情報をPushManager.getSubscription()を使って取得し、unsubscribe()関数はその後にPushSubscription.unsubscribe()を使って受信解除を行うことです。

適したエラーハンドリングもそれぞれの関数に提供されています。

ここでは説明の簡略化のためにsubscribe()関数のみ記載します。すべてのコードはGithub(subscribe/unsubscribe code on Github)を参照してください。

function subscribe() {
  // ボタンを無効状態にし、承認リクエストを処理している間に変更させない。

  subBtn.disabled = true;

  navigator.serviceWorker.ready.then(function(reg) {
    reg.pushManager.subscribe({userVisibleOnly: true})
      .then(function(subscription) {
        // 処理成功時
        isPushEnabled = true;
        subBtn.textContent = 'Unsubscribe from Push Messaging';
        subBtn.disabled = false;
        
        // サーバ上で現在のユーザがメッセージ受信できるように状態を変更する。
        // そして他のユーザに現在のユーザがメッセージを受診していることを知らせる。
        var endpoint = subscription.endpoint;
        var key = subscription.getKey('p256dh');
        updateStatus(endpoint,key,'subscribe');
      })
      .catch(function(e) {
        if (Notification.permission === 'denied') {
          // ユーザが通知承認リクエストを拒否した場合。
          // メッセージ受信を失敗したことになり、以降、ユーザはプッシュ通知を受信するために手動で通知承認を変更する必要がある。
          console.log('Permission for Notifications was denied');
          
        } else {
          // 問題が発生した場合
          // gcm_sender_id がない、またはgcm_user_visible_onlyの場合などに発生
          console.log('Unable to subscribe to push.', e);
          subBtn.disabled = false;
          subBtn.textContent = 'Subscribe to Push Messaging';
        }
      });
  });
}

アプリとサーバ上で状態を更新

メインのJavaScriptファイルで次に紹介する関数はupdateStatus()関数です。これはメッセージの受信/受信解除の切り替えをした時、その切り替えをサーバに送信し、メッセージ送信に関連したUIを更新します。

この関数は以下で紹介するstatusTypeパラメータに応じて、3つの異なった処理のうち1つだけを行います。

  • subscribe: チャットメッセージを送信するためのボタンとテキスト入力フォームが作成され、UIに追加される。そしてstatus type(subscribe)とユーザ名、エンドポイントと公開鍵を含むオブジェクトがXHRを経由して送信される。
  • unsubscribe: 基本的にsubscribeと真逆のこと行う。UIからメッセージを送信するためのコントロールが削除され、ユーザが受信解除したことをサーバに知らせる。
  • init: こアプリが最初に起動された時、初期化された時に実行される。チャットUIを作成し、どのユーザが初期化したかをサーバに知らせる。

しつこいようですが、説明の簡素化のためにすべてのコードは記載していません。Githubにあるコード(full updateStatus() code on Github)を確認してください。

service workerから送信されたchannel messageの制御

先述したとおり、service workerからのchannel messageが受信された時、handleChannelMessage()関数がこれを制御するために呼び出されます。これは私たちのハンドラーがmessageイベントとchannel.port1.onmessageのために実行します。

channel.port1.onmessage = function(e) {
  handleChannelMessage(e.data);
}

これはservice workerがchannel messageを送信した時(service worker sends a channel message over)に実行されます。

handleChannelMessage()関数は以下のような見た目です。

function handleChannelMessage(data) {
  if(data.action === 'subscribe' || data.action === 'init') {
    var listItem = document.createElement('li');
    listItem.textContent = data.name;
    subscribersList.appendChild(listItem);
  } else if(data.action === 'unsubscribe') {
    for(i = 0; i < subscribersList.children.length; i++) {
      if(subscribersList.children[i].textContent === data.name) {
        subscribersList.children[i].parentNode.removeChild(subscribersList.children[i]);
      }
    }
    nameInput.disabled = false;
  } else if(data.action === 'chatMsg') {
    var listItem = document.createElement('li');
    listItem.textContent = data.name + ": " + data.msg;
    messagesList.appendChild(listItem);
    sendInput.value = '';
  }
}

dataオブジェクトのactionプロパティによって以下のとおり異なった処理をします。

  • subscribe または init (初期化と再スタート、サンプルの中でこれらは同じことをする。): <li> エレメントが作られ、このエレメントのテキスト(受信者の名前)がdata.nameで設定され、これが受信者リスト(単純に<ul>エレメント)に追加される。これにより視覚的に受信者がチャットに参加したかどうかを確認できる。
  • unsubscribe: 受信者リスト内をループし、data.nameと同じテキストを見つけ、そのノードを削除します。
  • chatMsg: I最初のケースと同様に、<li>エレメントが作成され、テキストがdata.name + ": " + data.msg(例 "Chris: This is my message")で作成され、チャットメッセージリストに追加されます。このようにして、それぞれのユーザのUIにメッセージを表示しています。

チャットメッセージの送信

送信ボタンがクリックされた(Send Chat Message button is clicked)時、入力フォームに入力されたテキストがチャットメッセージとして送信されます。これはsendChatMessage()関数によって制御されます。すべてのコードはGithubにあります(sendChatMessage() function)。この関数はupdateStatus()関数に似ています(Updating the status in the app and serverを参照)。私はエンドポイントと公開鍵をPushSubscriptionオブジェクトから受け取ります。このオブジェクトはServiceWorkerContainer.ready()PushManager.subscribe()から受け取ります。これらはメッセージオブジェクトの中で受信者の名前とチャットメッセージ、そしてchatMsgstatusTypeと共にXMLHttpRequestを経由してサーバに送られます。 

サーバー

Note: サーバコンポーネントは現在理想的な状態ではありません。サーバサイド処理と静的なファイルを置くことしかできません。これは非効率的なだけでなく、たとえCORSを設定してもChromeでは動きません。私たちは現在これを作り直しています。

先ほど説明したように、私たちのアプリではプッシュメッセージの送信等を制御するためにサーバサイドのコンポーネントが必要です。NodeJSを使った簡単なサーバサイドコンポーネント(server.js)を作りました。これはクライアントサイドのJavaScriptコードから送信されたXHRリクエストを制御しています。

購読情報を保存するためにテキストファイル(endpoint.txt)を使っています。これは初期状態では何も書かれていないファイルです。リクエストには4つの異なる種類があり、リクエストで送られてきたオブジェクトのstatusTypeプロパティでその種類が決められています。クライアントサイドのコードで説明したものと同じコードで、同じ条件でサーバにリクエストをします。各コードのサーバサイドでの意味を以下に説明します。

  • subscribe: サーバは新しい受信者の情報をエンドポイントを含めて購読データ(endpoint.txt)に追加する。そしてチャットの参加者が加わったことを知らせるために、プッシュメッセージを保存しているすべてのエンドポイントに送信する。
  • unsubscribe: サーバは受信者の情報を購読データ(endpoint.txt)から見つけ、その情報を削除し、残っている全ての受信者にそのユーザがチャットから離脱したことを知らせる。
  • init: サーバは現在の受信者を購読データ(endpoint.txt)から読み取り、それぞれの受信者に一人のユーザが新規参加(あるいは再度参加)したことを知らせるためにプッシュメッセージを送信する。
  • chatMsg: 一人の受信者から全ての受信者へチャットメッセージを送信する。サーバは全ての現在の受信者を購読データ(endpoint.txt)から読み取り、それぞれのユーザへチャットメッセージを含んだプッシュメッセージを送信する。

注釈:

  • サーバを作るためにNode.jsのhttps moduleを使っている。これはセキュリティの目的で、service workersはセキュアコネクションの時だけ動作する。そのために私たちは.pfxセキュリティ証明書をアプリに含め、Node.jsでサーバを作る際にそれを参照する必要がある。
  • あなたがデータなしにプッシュメッセージを送信するとき、あなたは単にHTTP POST リクエストを利用してエンドポイントURLを送信している。しかしながら、プッシュメッセージがデータを含むとき、あなたはそのデータを暗号化する必要がある。これはかなり複雑な処理である。少し待てばその複雑な処理をしてくれるライブラリが現れるだろう。このデモでは私たちはMarco CastelluccioのNodeJS web-push libraryを使っている。暗号化処理を実現するのに、このコードを確認してみること、そしてさらに詳細な内容を知るためにMessage Encryption for Web Pushを読むことをお勧めする。ライブラリではプッシュメッセージの送信をシンプルに(makes sending a push message simple)してくれる。

Service worker

service workerのコード(sw.js)を見てみましょう。これはプッシュメッセージに応答します。これを動かすためのイベントハンドラはservice workerのスコープ(ServiceWorkerGlobalScope.onpush)で設定されます。最初にプッシュでオブジェクトに返信されたメッセージをPushMessageData.json()を使って変換します。次にそのプッシュメッセージがどの種類のものなのかをオブジェクトのactionのプロパティで以下のように確認します。

  • subscribe or unsubscribe: fireNotification()関数を使ってシステム通知を送る。同時にメインコンテキストへchannelメッセージを送り返す。これによって受信者リストを更新することができる。詳細はHandling channel messages sent from the service workerを参照。
  • init or chatMsg: initchatMsgを制御するためにchannelメッセージをメインコンテキストへ送り返す。これらはシステム通知を必要としない。
self.addEventListener('push', function(event) {
  var obj = event.data.json();

  if(obj.action === 'subscribe' || obj.action === 'unsubscribe') {
    fireNotification(obj, event);
    port.postMessage(obj);
  } else if(obj.action === 'init' || obj.action === 'chatMsg') {
    port.postMessage(obj);
  }
});

fireNotification()関数を見てみましょう。ここではタイトルやボディ、アイコンなど通知の異なる部分を定義しています。そして通知をServiceWorkerRegistration.showNotification()メソッド経由で送信します。さらにExtendableEvent.waitUntil()メソッドの内側にこれを包括します。これはservice workerが通知が送られるまでアクティブであることを確認するためです。service workerのライフサイクルはこのメソッドの内側の処理が全て完了するまで延長されます。

function fireNotification(obj, event) {
  var title = 'Subscription change';  
  var body = obj.name + ' has ' + obj.action + 'd.';
  var icon = 'push-icon.png';  
  var tag = 'push';
   
  event.waitUntil(self.registration.showNotification(title, {
    body: body,  
    icon: icon,  
    tag: tag  
  }));
}

Note: service workersからのWeb通知はFirefox version 42で紹介されました。しかしClients.openWindow()などの機能が実装されることによって削除されるようです。詳しくはバグ 1203324を参照してください。

購読の期限切れの制御

時々プッシュ通知の購読がPushSubscription.unsubscribe()が呼ばれることなく、期待しているより早く期限切れになってしまうことがあります。これはサーバが過負荷な状態の時か、長い間ユーザがオフラインになっている時などに発生します。これはサーバに強く依存しており、具体的な挙動を予想することは難しいです。どのような場合でも、あなたはこの問題をServiceWorkerGlobalScope.onpushsubscriptionchangeを使うことで制御できます。このハンドラはこの特定の場合にのみ実行されます。

self.addEventListener('pushsubscriptionchange', function() {
  // ここに動作を記述する。普通は再度プッシュ通知を受信するとき、
  // 新しい購読データをXHRかFetchで送り返すとき
});

デモではこれについて触れません。購読の終了についてはこのデモでは重要なことではないからです。しかし、より複雑なアプリではこれが必要になるでしょう。

Chromeをサポートする

私たちのアプリをchromeで動かすためにはさらなる実装が必要です。Chromeは現在Push通知を使うためにGoogle's Cloud Messaging serviceに依存しているからです。

Google Cloud Messagingの設定

これを設定するために、以下の手順に従ってください。

  1. Google Developers Consoleへ移動し、新しいプロジェクトを設定。
  2. プロジェクトのホームページへ移動。(私たちの場合https://console.developers.google.com/project/push-project-978
    1. Enable Google APIs for use in your appsを選択。
    2. 次の画面で、Mobile APIsセクションにあるCloud Messaging for Androidをクリック。
    3. Enable APIボタンをクリック。
  3. 後の手順で使うProject numberとAPI keyを以下の手順で見つける。
    1. Project number: 左側にあるHomeをクリック。project numberはプロジェクトのホームページの上部に記載されている。
    2. API key: 左側のメニューにあるCredentialsoクリック。API keyは画面上に表示される。

manifest.json

Google app-style manifest.jsonファイルをアプリに含める必要があります。これはgcm_sender_idでProject numberを参照します。これは私たちのシンプルな例です。manifest.json

{  
  "name": "Push Demo",  
  "short_name": "Push Demo",  
  "icons": [{  
        "src": "push-icon.png",  
        "sizes": "111x111",
        "type": "image/png"
      }],  
  "start_url": "/index.html",  
  "display": "standalone",  
  "gcm_sender_id": "224273183921"    
}

さらに、HTMLの中で<link> を使ってmanifestを参照する必要があります。

<link rel="manifest" href="manifest.json">

userVisibleOnly

ChromeはPushサービスを有効にするためにuserVisibleOnly parametertrueを設定するよう要求します。 これはプッシュを受信したら通知を表示することを示します。これはsubscribe()関数内で実装されています(seen in action in our subscribe() function)。

参考

ドキュメントのタグと貢献者

 このページの貢献者: wataruoguchi
 最終更新者: wataruoguchi,