やっと、チャット擬きが作れたよ。
僕レベルじゃチャットも作れないのかと、何度も諦めそうになったけれど、楽しいから、もがてみた。子供のおもちゃのようなコードなんだろうけれど、何となく動いてくれたので、とりあえず。
(二重投稿防止とか、リロード関連の処理とか、そういうのはやってません。)
DB
テーブル:Chat
カラム | 内容 |
---|---|
comment | 投稿コメントを記録 |
created_at | フィールド作成日時を記録 |
流れ?
1.サイトインの時に日時を取得
2.SSEで、1もしくは3 の日時以後のログを出力
3.ajaxで画面遷移せずにコメント登録して、ログを出力し、登録日時を取得
各日付は更新日時として$_SESSION['CURRENT']で管理
controller
controller
// サイトIN時に、日時をSESSIONに更新日時として記録
public function index(){
session_start();
$_SESSION['CURRENT'] = date('Y-m-d H:m:s');
return view('index');
}
// 更新日時以降のコメントがあれば、クライアントに送信し
// 更新日時を最新のコメント日時に更新
public function sse(){
session_start();
$comment = Chat::all()->toArray();
header('Content-Type:text/event-stream');
foreach($comment as $value){
if($value['created_at'] > $_SESSION['CURRENT'] ){
echo 'data:'.$value['comment'];
echo "\n\n";
flush();
}
}
$current = Chat::orderBy('created_at','desc')->first()->toArray();
if($current['created_at'] > $_SESSION['CURRENT']){
$_SESSION['CURRENT'] = $current['created_at'];
}
}
// ajaxで送信されてきたコメントを登録し、更新日時を更新
public function ajax(Request $request){
session_start();
$comment['comment'] = $request->comment;
if(isset($comment['comment'])){
$chat = new Chat;
$chat->fill($comment)->save();
}
$comment = Chat::orderBy('created_at','desc')->first()->toArray();
$_SESSION['CURRENT'] = $comment['created_at'];
return response($comment);
}
クライアント側
index.blade.php
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function(){
var commentInp = $('input[name="comment"]');
// sse
var source = new EventSource('sse');
source.onmessage = function(chat){
$('div[name="comment"]').prepend('<p>'+chat.data);
}
// ajax
$('form').submit(function(){
comment = commentInp.val();
$.ajax({
type : 'post',
url : 'ajax',
data :{'comment':comment,_token:'{{csrf_token()}}'},
}).then(
function(chat){ $('div[name="comment"]').prepend('<p>'+chat['comment']);},
function(){},
);
return false;
});
});
</script>
<form>
<input type="text" name="comment"/>
<button>send</button>
</form>
<div name="comment"></div>
今の僕には、このコードが限界。
websocketとか、プロトコルを操る人に羨望!
僕には無理かなー。
ITに関係ない一言
子供とね、試作チャットで遊んでたんだけど、リアルタイムに発言が反映されないので、使いづらいって言われたのです。3か月前のことなんだけれど。
んで、リアルタイムに発言を表示できるようにしようと試みたんだ。でも、こんな時間がかかるとはね、僕の脳は優秀ではないようですな。