背景
- バックグラウンドで発生した変更を、ユーザーが手動でページを更新することなく、能動的にリアルタイムでブラウザに配信する必要性。
- 例:チャットルーム、リアルタイム見積システム、オンラインゲーム
- httpの欠陥:通信はクライアントによってのみ開始可能
polling
ポーリングとは、クライアントとサーバーの間の接続のことです。
- サーバー時刻のリアルタイム表示
<body>
 <div>
  
 </div>
 <div class = "clock"></div>
 <script>
 function getTime() {
 let xhr = new XMLHttpRequest()
 xhr.open('get', '/polling')
 xhr.onload = () => {
 let content = xhr.response
 let clock = document.querySelector('.clock')
 clock.innerText = content
 }
 xhr.send()
 }
 getTime()
 setInterval(getTime, 1000)
 </script>
</body>
const Koa = require('koa')
const serve = require("koa-static");
const Router = require("koa-router");
// 時刻のフォーマット
const moment = require('moment')
const app = new Koa()
const router = new Router()
app.use(serve(__dirname + '/static'))
router.get('/polling', (ctx) => {
 ctx.body = moment().format()
})
app.use(router.routes())
app.listen(8080, () => {
 console.log('open 8080')
})
長所
実装が簡単で、多くの変更を加える必要がありません。
デメリット
- ポーリング間隔が長すぎると、ユーザーは更新されたデータをタイムリーに受け取ることができません。
- ポーリング間隔が短すぎると、クエリーリクエストが多くなり、サーバー側の負担が増えます。
SSE Server-Sent Events
実装原理
- サーバーはクライアントに、次に送信するのはストリーム・メッセージであると宣言します。
- 長いダウンロードをストリーミングメッセージとして完了します。
- ストリーミング情報- 1回限りのパケットではありません
- 継続的に送信する必要があるデータのストリームです。
- クライアントは接続を閉じずに待機
 
長所
- 既存のサーバーソフトウェアでサポートされているHTTPプロトコルを使用します。
- 軽量で使いやすい
- デフォルトで切断と再接続をサポート
- 送信されるメッセージの種類のカスタマイズをサポート
サーバー時刻のリアルタイム表示
EventSource
<body>
 時刻表示
 <div class="block"></div>
 <script>
 // 共通アドレスの共有& ip 先頭アドレスを書く必要がない
 const eventSource = new EventSource("/sse");
 eventSource.addEventListener("open", (e) => {
 console.log("open");
 console.log(e);
 });
 eventSource.addEventListener("message", (e) => {
 console.log("message");
 console.log(e);
 document.querySelector('.block').innerText = e.data
 });
 eventSource.addEventListener("sock", (e) => {
 console.log("sock");
 console.log(e);
 document.querySelector('.block').innerText = e.data
 });
 eventSource.addEventListener("error", (e) => {
 console.log("error");
 console.log(e);
 });
 </script>
 </body>
const http = require("http");
const fs = require("fs");
const moment = require("moment");
const server = http.createServer((req, res) => {
 // fs
 // インターフェース
 if (req.url === "/sse") {
 // イベントストリームに設定する必要がある
 res.setHeader("content-type", "text/event-stream");
 // 固定フォーマットのデータ: xxxxx
 setInterval(() => {
 // トリガーするものを指定する
 res.write("event: sock
")
 //  
 このデータが終了したことを示し、上段と下段が1つのデータであることを示す
 res.write(`data: ${getDate()}
`);
 }, 1000);
 // 終了を書かないこと
 // sse
 } else {
 // 静的サービス
 const readStream = fs.createReadStream("./static/index.html");
 readStream.pipe(res);
 }
});
function getDate() {
 return moment().format("MMMM Do YYYY, h:mm:ss a");
}
server.listen(3000);
websocket
特徴
- 二重通信
- クロスドメインの許可
- TCPで構築
- 持続的接続を確立するには、httpハンドシェイクを1回行うだけです。
- データフォーマットは比較的軽量で、パフォーマンスのオーバーヘッドが少なく、効率的な通信が可能です。
- テキストまたはバイナリデータを送信できます。
- 同一オリジン制限なし
- プロトコル識別子はws
デメリット
- 互換性の問題





