質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

198閲覧

チャットをSSEでやってみようと思っていますが、SSEは下に繰り返し追加されてしまいます。

system-r

総合スコア7

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2025/05/23 02:45

チャットをAjaxで実装しましたが、失敗する時があるのでSSEでやってみようと思っていますが、Ajaxはチャットが上書きされますが、SSEは下に繰り返し追加されます。

同じチャットは1回出力されればよくて、新しいチャットが2行分追加されたらそれのみ追加で出力したいです。その時古いチャット2行分は表示されなくなる。チャットは直近の18行のみ表示したいです。

●サーバー側
while (true) {
$curDate = date(DATE_ISO8601);
echo "data: The server time is: {$curDate}\n\n";
echo "data: Random number: {$counter}\n\n";
$counter++;

ob_flush(); flush(); sleep(3);

}

●クライアント側
source.onmessage = function(event) {
var resultDiv = document.getElementById('result');
resultDiv.innerHTML += event.data + '<br>';
};

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2025/05/23 03:23

チャットの仕様がわからないので何をどう実装すべきか提示できないですね。チャットのデータ保存方法はRDBですかファイルですか?個々の文書にはIDをつける想定ですか? ちなみにSSEはPHP(もしくはその他サーバーサイドアプリ)側の処理なのでタグにPHPは入れておいてください
utm.

2025/05/23 05:12

全件取得して常に全て上書きすれば簡単なのでは?
yambejp

2025/05/23 07:43

chatとして動作する内容を追記しておきました
guest

回答1

0

簡単なSSEの実装

sseapi.php

php

1<?PHP 2header("Cache-Control: no-store"); 3header("Content-Type: text/event-stream"); 4date_default_timezone_set("Asia/Tokyo"); 5while (true) { 6 $t=date("Y-m-d H:i:s"); 7 print "data:{\"event\":\"message\",\"time\":\"$t\"}".PHP_EOL.PHP_EOL; 8 ob_end_flush(); 9 flush(); 10 if ( connection_aborted() ) break; 11 sleep(1); 12}

上記を利用してjsでこう呼び出す

html

1<script> 2const evtSource = new EventSource("sseapi.php",); 3evtSource.onmessage = function (event) { 4console.log(event.data ); 5}; 6</script>

chatの実装

だいぶ端折ってますが最低限動く範囲で実装しておきます
chat.html

html

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 const box=document.querySelector('#box'); 4 const message=document.querySelector('#message'); 5 const send=document.querySelector('#send'); 6 send.addEventListener('click',e=>{ 7 const usp=new URLSearchParams(); 8 if(message.value){ 9 usp.append('m',message.value); 10 fetch('sendapi.php?'+usp); 11 message.value=''; 12 } 13 }); 14 message.addEventListener('keydown',e=>{ 15 if(e.key=="Enter"){ 16 send.click(); 17 } 18 }); 19}); 20const evtSource = new EventSource("sseapi.php",); 21evtSource.onmessage = function (event) { 22 const json=JSON.parse(event.data); 23 box.appendChild(Object.assign(document.createElement('div'),{textContent:json.message})); 24 box.scrollTop = box.scrollHeight; 25}; 26</script> 27<style> 28#box{ 29width:500px; 30height:300px; 31background-Color:lightgray; 32overflow-Y:scroll; 33} 34</style> 35<div id="box"> 36</div> 37<input id="message"><input type="button" id="send" value="send">

sendapi.php

php

1<?PHP 2$m=filter_input(INPUT_GET,"m"); 3if($m){ 4 $filename="chat.txt"; 5 $file = new SplFileObject($filename, "a+"); 6 $file->fwrite('['.microtime(true).']'.$m.PHP_EOL); 7}

sseapi.php

php

1<?PHP 2header("Cache-Control: no-store"); 3header("Content-Type: text/event-stream"); 4date_default_timezone_set("Asia/Tokyo"); 5$mt=microtime(true); 6while (true) { 7 $filename="chat.txt"; 8 $file = new SplFileObject($filename, "r"); 9 foreach ($file as $line) { 10 if(preg_match("/^\[([\d\.]+)\](.+?)$/",$line,$match)){ 11 if($match[1]-$mt > 0){ 12 print "data:{\"message\":".json_encode($match[2])."}".PHP_EOL.PHP_EOL; 13 } 14 } 15 ob_end_flush(); 16 flush(); 17 } 18 if ( connection_aborted() ) break; 19 $mt=microtime(true); 20 sleep(1); 21}

投稿2025/05/23 03:28

編集2025/05/23 07:42
yambejp

総合スコア117726

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

system-r

2025/05/25 07:44

チャット日時 5時23分:チャット1 チャット日時 5時21分:チャット2 チャット日時 5時16分:チャット3 ファイルを開いた時に上記の3行分を一度に表示して、 その後 5時25分:チャット0が追加されたら チャット日時 5時25分:チャット0 チャット日時 5時23分:チャット1 チャット日時 5時21分:チャット2 の3行を表示したいです。 前に出力したチャットを消すことが出来れば できるのではないかと思いますが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問