Server-Sent Eventsについて

javascript

Server-Sent Eventsについて

Server Sent Eventsを使ってサーバ側からクライアント側への通信をする方法があります。

通信時にはEventSorceオブジェクトのインスタンスを生成し、そのコンストラクタに
サーバ側のURLを渡します。

サーバ側では、任意の処理を行い、クライアント側に処理結果を返し、
クライアント側では返されたオブジェクトのmessageイベントを処理します。

messageイベントには、dataプロパティがあり、サーバ側から返された文字列が格納されています。

また、typeプロパティにはデフォルトでmessageが格納されています。
実装の仕方によっては、サーバ側から返されたイベントソースが複数あり、その全てのイベントを受取る方法として
typeプロパティを使うこともあります。

Server-Sent Eventsのプロトコルについて

Server-Sent Eventsのプロトコルについては、HTTP/1.1で動作します。
これは1回のリクエスト&レスポンス(通信)で、1つの送信&受信を行う。と定義されています。

(ちなみにHTTP/2では、一回の通信で、複数の送信&受信をまとめて通信することができます)

EventSorceオブジェクトのインスタンスを生成したときに、クライアントサーバに接続されます。
サーバ側はこの接続をオープン状態のまま維持します。

サーバ側の処理について

サーバ側の処理は、Server-Sent Eventsで接続されているオープン状態の接続に対してテキストを送信します。
その際の「Content-Type」は以下のようにします。

Content-Type: text/event-stream

また、サーバ側では、「データ名:値」のセットになるように文字列を出力します。
データ名は任意で大丈夫ですが、クライアント側と合わせる必要があります。

例えば次のようになります。

data: sample123

テキストが送信されると、クライアント側でイベントが発生して、その内容を受信および処理ができます。

ここまでをふまえて、簡単なHTMLを用意しました。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<div id="sse"></div>

<script type="text/javascript">

// データ確認用のdivタグ
let dom_sse = document.getElementById("sse");

// EventSorceオブジェクトのインスタンスを生成
let testsse = new EventSource("server_sent_event.php");

// サーバ側から応答があった時の処理
testsse.onmessage = function(event) {

	// サーバ側から送られた内容を受信し、JSONパースをする
	let recieve_data = JSON.parse(event.data);

	// ログ出力で内容確認
	console.log("recieve_data.data1 -> " + recieve_data.data1);
	console.log("recieve_data.data2 -> " + recieve_data.data2);

	// サーバ側から受信したテキストをDOMへ描画(data1のみ)
	dom_sse.innerHTML += recieve_data.data1 + "<br />";

}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

サーバ側のphpは次のように書きました。
「Content-Type」を「text/event-stream」にしている点と、
出力するデータの名称を「data:」として、値をjson形式にしている点、
それと、「ob_end_flush();」と「flush();」で、出力方法を制御している点に注意が必要です。

<?php

// server_sent_eventデモ

header("Cache-Control: no-store");
header("Content-Type: text/event-stream");

$sample_data = date("Y/m/d H:i:s");

// 返却用のサンプルデータを用意
$result_arr = array(
	"data1" => $sample_data,
	"data2" => "test1234"
);

echo "data: " . json_encode($result_arr) . "\n\n";

ob_end_flush();
flush();

?>

画面にアクセスして動きをみると、画面上に時刻が表示されることがわかります。
(日時はダミーです)

onmessageのテスト
2022/09/07 21:22:21
2022/09/07 21:22:24
2022/09/07 21:22:27
2022/09/07 21:22:30

また、通信が行われるタイミングは約3秒ごとに発生していますが、
これはどこで制御されているのかは不明なので、改めてわかった時点で内容を更新しようと思います。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です