はじめに
1990年代に HTTP1.x が登場して以来、その技術を応用した様々なプロトコルが誕生してきました。その中で、サーバーからクライアントにデータを送信する技術「Push技術」も進歩しています。
LINEやTwitter、FacebookをはじめとするSNSでは、友人の誰かが「書込み」したことをアプリを起動しなくても通知されてきますよね。この通知機能に欠かせないのが「Push技術」です。
本記事は、サーバーからクライアントに情報をPushする技術の進歩を時系列でまとめています。
こんな方におすすめ
- サーバーPush技術にどのようなものがあるか知りたい
- サーバーPush技術について、これまでの進化の流れを知りたい
語句説明:Push技術とは?
Wikipedia では、以下のように記載されています。
Push技術あるいはserver pushはインターネット上での通信方法の一つであり、ある通信リクエストが送り手側(中央サーバ)により開始されるものを指す。これはPull技術と対比され、こちらは通信のリクエストはクライアントにより開始される。
通常の通信において、HTTPではクライアントから通信(HTTP Request)を始め、サーバーからの応答(HTTP Response)で終わるプロトコルです。これをPull技術と言います。
例えば、ブラウザにURLを入れてEnterを押す、リンクをクリックする、などクライアント側契機で通信が始まり、Webページを表示するための情報をサーバー側からもらって通信が完了するプロトコルです。
対して、サーバー側から通信を始め、クライアントに情報を送信する技術を Push技術と言います。

Push技術の歴史
これから紹介する技術の一覧です。
それぞれどのような技術で、どのような欠点があって進歩してきたのでしょうか。
詳しくみていきましょう。
技術 | 出現 年代 |
プロトコル | 規格 | Pushごとの 再接続 |
サーバー プッシュ |
サーバー 負荷 |
リアル タイム性 |
---|---|---|---|---|---|---|---|
ajax (疑似Push) | 2005年 | HTTP | 要 | × | × | × | |
HTTP Comet | 2007年 | HTTP | RFC6202 | 要 | ○ | △ | △ |
Server Sent Events |
2009年 | HTTP | W3C CR | 不要 | ○ | ○ | ○ |
WebSocket | 2011年 | WebSocket | RFC6455 | 不要 | ○ | ○ | ◎ |
MQTT | 2014年 | TCP or WebSocket |
OASIS | 不要 | ○ | ○ | ◎ |
HTTP/2 Server Push |
2015年 | HTTP/2 | RFC7540 | 不要 | ○ | ○ | ◎ |
WebPush | 2017年 | HTTP/2 or WebSocket |
RFC8030 | 不要 | ○ | ○ | ◎ |
技術①:ajax (疑似Push) [2005年ごろ]
技術の概要

ajaxによるPushシーケンス(疑似Push)
クライアント契機によるPush技術のため「疑似Push」や「ポーリング」と呼ばれています。
クライアント側から HTTP Request(GETメソッド)を投げ、サーバーがHTTP Response を返します。
HTTP Response の内容によって、画面を更新したり情報の変化を検出します。
従来の HTTP1.x 仕様で実現できるため、最古のPush技術と言っても良いでしょう。
JavaScript では XMLHttpRequest を使って実装され、HTTP Response は JSON が主流です。

メリット
- (そうとう)古いシステム、ブラウザでも動作する
- 枯れた技術のため、ノウハウがネット上にたくさんある
デメリット
- クライアント契機のため、リアルタイム性が低い(クライアント側のHTTP Request間隔に依存)
- 何度もコネクションを確立させるため、接続クライアント数、間隔に比例してサーバー負荷が高くなる
技術②:HTTP Comet [2007年ごろ]
技術の概要

HTTP Coment による Push シーケンス
ajax によるPush技術の欠点「クライアント契機」「サーバー負荷」を少し解消した技術です。
クライアントからの HTTP Request に対する応答をサーバー側で保留します。
何か変化があった場合、またはタイムアウトした場合に HTTP Response を返します。
サーバー側で保留できるようにしたため、完全なクライアント契機から脱出。
また、通信量が減るためサーバー負荷が軽減されます。
欠点としては、連続して HTTP Response を返せないことです。
HTTP Response を返した後から、次の HTTP Request が来るまでの期間(上図の赤丸)は、変化が起きてもサーバー側から送信することができません。
メリット
- ajax(ポーリング)に比べ、リアルタイム性が高い
- イベントが発生するまで保留することで通信量・サーバー負荷を低減できる
デメリット
- 連続してイベントが発生した場合、HTTP Response を送信できない期間がある
- 保留中、接続待ちなどの状態が増えるため、実装が複雑になる
スポンサーリンク
技術③:Server-Sent Events (SSE) [2009年ごろ]
技術の概要

Server-Sent Events による Push シーケンス
HTTP Comet の欠点である「短期間での連続送信」を解消した技術で、W3C で標準化されています。
HTTP1.x で定められている 「Transfer-Encoding: chunked(チャンク方式)」を使用します。
ストリーミングなど、サーバーから送信するデータサイズが決まっていない場合、
ある一定の塊ごとに分割してクライアントへ送信する方式です。
HTTP コネクションを持続させているため、HTTP Comet のように再接続によるタイムラグがありません。
また、状態管理も容易になるため、実装も複雑になりません。

メリット
- 一度サーバーPushを受けた後にクライアントが再接続するという手間と性能劣化がない
- HTTP1.x に準拠した技術であり、従来技術の延長で実現可能
デメリット
- テキストベースの HTTP プロトコル、セキュリティなども HTTP 継承のため効率が悪い
- クライアント側は待ち状態のため、新たな HTTP Request を投げるには別のコネクションが必要
スポンサーリンク
技術④:WebSocket [2011年ごろ]
技術の概要

WebSocket による Push シーケンス
これまでの技術の欠点「HTTPプロトコルによる縛り」を取り払った技術です。RFC6455 で標準化。
TCP層に等しいコネクションを接続し続け、独自の WebSocket プロトコルで通信します。
プロトコルは、wss または ws と表記されます。
全2重双方向通信が可能となっており、TCP層に近いプロトコルのためヘッダが軽量です。
HTTP に比べてサーバーが使用するリソース・通信負荷が少なく、リアルタイム性も高いです。
バイナリの送受信も可能です。
WebSocket のコネクションを確立する際、HTTP の UPGRADE を使ってプロトコルを変更します。
そのため、通信経路上にあるルーターや proxy などに遮断される場合があるため注意が必要です。
メリット
- HTTPプロトコルと比較して、サーバー負荷が軽く、リアルタイム性が高い
- 双方向通信が可能であり、バイナリ転送も可能
デメリット
- 通信機器や proxy によっては遮断される場合がある
- 送達確認はWebSocketを使う側(アプリ層)で実装が必要
スポンサーリンク
技術⑤:MQTT (Message Queuing Telemetry Transport) [2014年ごろ]
技術の概要

MQTT による Push シーケンス
これまでの HTTP1.x を使った仕組みは、クライアント・サーバーモデルです。
クライアントとサーバーが直接コネクションを確立するため、莫大なクライアントとの通信に不向きでした。サーバーが安定したサービスを提供するには、莫大なクライアントの相手をしている余裕はありません。また、スマートフォンなどは電波が安定していない場合も多いため、再送が発生すると更にサーバー負荷が上がります。
この問題を解決するため、MQTT が誕生しました。MTQQは PubSub モデルになります。
上図ではサーバー側からPushするシーケンスを示していますが、クライアント側も Publish することが可能です。
サーバーもクライアントも Broker と呼ばれる仲介役とコネクション(TCPまたはWebSocket)を確立します。どのメッセージをどのクライアント、サーバーに配信したかは Broker が全て管理します。

メリット
- TCP または WebSocket でコネクションを確立するため、ネットワーク負荷軽減
- 莫大な数のクライアントへ Push 通知(センターPush)を送ることができる
デメリット
- HTTPのようにレスポンスコードが無いため、実運用システム構築はハードルが高い
- サーバー(Broker)の冗長構成をとることが難しい
スポンサーリンク
技術⑥:HTTP/2 Server Push [2015年ごろ]
技術の概要

HTTP/2 Server Push による Push シーケンス
HTTP1.x から他のプロトコルに派生したものの、HTTP の進化系として誕生したのが HTTP/2 Server Push です。HTTP/2 のプロトコルについては、Introduction to HTTP2 が分かりやすいと思います。
HTTP/2の概要

StreamとFrameの関係
(出典:https://developers.google.com/web/fundamentals/performance/http2)
HTTP/2のポイント
- HTTP1.x の Header と Payload が分離され、Frame という概念に変化
- stream id で従来の Request-Response のペアを表現
- 優先順位を付与することも可能、Frame の送信はパイプライン
- バイナリ転送、Header 圧縮などで性能面も改良
話を戻して HTTP/2 Server Push のシーケンス
Frame には種類があり、PUSH_PROMISE を使ってサーバーがクライアントへ Push するリソースを事前に予約します。予約することでコネクションが維持され、HTTP Request で要求されていないリソース(Push Data)を後ほどサーバーが返すことができるようになります。
メリット
- バイナリ転送、Header圧縮、パイプライン化など、通信効率が良い
- HTTP1.x の後継であり、メソッドやレスポンスコードなどが同一なため、既存資産との相性が良い
デメリット
- セキュリティ要求があり HTTPS でしか通信できないクライアントが多い
- 複数ドメインからリソースを取得する場合は従来の HTTP1.x と大差がない
スポンサーリンク
技術⑦:WebPush [2017年ごろ]
技術の概要

WebPush による Push シーケンス
WebPush は、HTTP/2 の仕組みを利用して RFC8030 で規格化されました。
Push Service を中継し、クライアントとサーバーが Pub-Sub モデルで通信を行います。
まず、クライアントが Push Service に Subscribe を通知し、サーバーが Push する送信先の URL(endpoint)と暗号化のための鍵を受け取ります。受け取った URL と鍵をサーバー側へ通知して準備完了です。
サーバー側がデータを送信したいタイミングで、通知された endpoint に対して POST メソッドを発行します。すると、仲介役の Push Service が対応するクライアントへ Push Message を送信(Pusblish)します。
クライアントと Push Service の間は、HTTP/2 または WebSocket が利用されることが多いです。

メリット
- PushAPI が最近のブラウザには実装されており、クライアント側の対応が容易
- クライアントごとに endpoint(URL) が異なるため、Push 先をきめ細やかに制御可能
デメリット
- まだ技術ノウハウが少ないため、Push Service/Server の構築ハードルが高い
- 受信するクライアントごとに異なる鍵で暗号化する必要がある
スポンサーリンク
まとめ
いかがでしたでしょうか。
Web の世界で進化を続ける Push 技術の歴史を、それぞれの技術が誕生した理由やメリット、デメリットを含めて紹介いたしました。
古い技術(WebSocketぐらいまで)においては、ブラウザを始め様々な Webコンテナ(Tomcatなど)でもパッケージが用意されているため、サーバー側・クライアント側ともに実装が容易になっています。
しかし、新しい技術については、MQTTだと ActiveMQ(OSS)、WebPush だと GitHub で公開されているようなモジュールしか現状は無く、技術情報が少ないためサーバー側の実装はハードルが高そうです。
システムに導入する際は、どのぐらいのリアルタイム性を求めるのか、Push 送信するクライアント数、などを考慮して技術を選定する必要があります。
以上、「【まとめ】サーバーからPushする技術の進化」でした。