JavaScriptとPHPでリアルタイムチャットを製作しているのですが、どうやって現在の入室者数をカウントするかで嵌っています。
入室者数を記録するファイルを用意して、入室したらPHP側で1足して、退室したら1引く、とすればいいんですが、
問題は途中でページを離脱した際の処理です。
チャットには「退室ボタン」を用意するつもりですが、押さずに別のページに移行するユーザーもいます。
そういう時は、パソコンならJavaScriptの「beforeunload」でPHPにデータを送信して、
途中でページを離脱した際でも退室扱いにする事が出来ます。
しかし、スマホ・タブレット用の「pagehide」では、同じタブ(ウィンドウ)でページ移行したり、ページを更新した際にはイベントが実行されるのですが、タブを閉じた際には実行されないのです。
そうなると、もしユーザーが「退室ボタン」を押さずにタブを閉じた際、入室者数に誤差が発生することになります。
これをなんとか解決したいのですが、どうすればいいでしょうか?
ご提示よろしくお願いいたします。
==2019/07/25 追記==
mikkameさん、mts10806さんから頂いたヒントから、自分なりに考えてコードを組んでみました。
php
1session_id(sha1(uniqid(microtime())));
まずチャットにアクセスした際に、セッションIDを作成しておきます。
javasctipt
1function chatOnline(){ 2 $.ajax({ 3 type: "post", 4 url: "php/usercount.php", 5 data: { Penname: userName }, 6 timeout: 10000, // 単位はミリ秒 7 8 success: function(result, textStatus, xhr) { 9 onlineTimer = setTimeout( "chatOnline()", 10000 ); 10 }, 11 // 通信失敗時の処理 12 error: function(xhr, textStatus, error) { 13 14 } 15 }); 16} 17 $.ajax({ 18 url: 'php/usercount.php', 19 type: 'GET', 20 dataType: 'json', 21 data: {ut: (new Date().getTime())} 22 }) 23 .done(function(result) { 24 if(result){ 25 $("hoge").html('現在の入室者数:' + result[0].usercount + '人'); 26 } 27 });
javasctiptで10秒ごとにPHPにデータを送信します。
PHP
1<?php 2session_start(); 3if($_SERVER["REQUEST_METHOD"] == "POST"){ 4 mb_language("uni"); 5 mb_internal_encoding("utf-8"); //内部文字コードを変更 6 mb_http_input("auto"); 7 mb_http_output("utf-8"); 8 9 date_default_timezone_set('Asia/Tokyo'); 10 11 if(isset($_POST['Penname'])){ 12 $json = file_get_contents('../data/log/userlog.json'); 13 $records = json_decode($json, true); 14 15 $Id = session_id(); 16 $Penname = htmlspecialchars($_POST["Penname"]); 17 $Time = time(); 18 19 $result_index = array_keys(array_column($records, 'id'), $Id); 20 21 if($result_index == null){ 22 $records[] = [ 23 'id' => $Id, 24 'time' => $Time, 25 'penname' => $Penname, 26 ]; 27 }else{ 28 foreach ($records as $key => $value) { 29 $nowtime = $Time; 30 $lasttime = $value['time']; 31 if(($nowtime - $lasttime) > 60){ 32 unset($records[$key]); 33 }else{ 34 foreach ($result_index as $index) { 35 $records[$index]['time'] = $Time; 36 } 37 } 38 } 39 } 40 41 $out_json = json_encode($records); 42 43 $result = file_put_contents("../data/log/userlog.json", $out_json, LOCK_EX); 44 } 45} 46if($_SERVER["REQUEST_METHOD"] == "GET"){ 47 $json = file_get_contents('../data/log/userlog.json'); 48 $records = json_decode($json, true); 49 $Num = count($records); 50 $usercount[] = [ 51 'usercount' => $Num, 52 ]; 53 54 echo json_encode($usercount); 55} 56?>
PHPでは、リクエストがPOSTの場合は、ユーザー別にセッションIDや最終アクセス時間などをファイルに記録します。
最終アクセス時間が1分を過ぎても変更されない場合、ファイルからデータを削除します。
リクエストがGETの場合は、現在の入室者数を返します。
以上です。
回答2件
あなたの回答
tips
プレビュー