こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

-広告-

解決済みの質問

PHP チャットの相手の入場時にチャイム鳴動

下記のPHPスクリプトで、自分が先にチャットのページを開いていたとして、
相手がチャットのページを開いたら(入場したら)チャイムを鳴動させたいのですが、
相手が入場したときに、相手側にしか音が鳴りません。こちらは、相手がいつ入場したのか
わかるために、チャイムを鳴動させたいのですが、どこがどう間違っているのでしょうか。
ご指導よろしくお願い致します
---------------------------------------------------------------------------------------------------
///////////////////////////////////////////////////
// IPアドレスをファイルに保存 //
///////////////////////////////////////////////////
function reserveIpAdress(){
$filename="ip_log.txt";
if(!filesize($filename)){ // ファイルが空だったら
$fp = fopen($filename, 'w'); // 追加書き込み用に、IPログファイルをオープン
$buf = $_SERVER['REMOTE_ADDR']."\n";
fwrite($fp, $buf); // IPアドレスを追加書き込み
fclose($fp);
echo '<audio src="http://5247423.raindrop.jp/chat/music/schjoin.hso" autoplay></audio>';
$_SESSION['ip_write_cnt']++;
}else{
$fp = fopen($filename, 'r');
//while(($buf=fgets($fp))===false){
$buf = fgets($fp); // 1行目
//$buf1 = rtrim($buf1);
//$buf2 = fgets($fp); // 2行目
fclose($fp);
if(rtrim($buf)!==$_SERVER['REMOTE_ADDR']){ // 相手の方が先にチャットにアクセスした時
$fp = fopen($filename, 'a');
$buf2 = $_SERVER['REMOTE_ADDR']."\n"; // 自分のIPアドレスをファイルにライト
fwrite($fp, $buf2);
fclose($fp);
echo '<audio src="http://5247423.raindrop.jp/chat/music/schjoin.hso" autoplay></audio>'
}else{
}
$_SESSION['ip_write_cnt']++;
}
}

///////////////////////////////
// メインルーチン //
///////////////////////////////
session_start(); // セッション開始
if(is_null($_SESSION['ip_write_cnt'])) $_SESSION['ip_write_cnt'] = 0;
if($_SESSION['ip_write_cnt']<2){ // 2人でチャットする場合
reserveIpAdress(); // このページにアクセスしたデバイスのIPアドレスをファイルにライト
}

以下略

投稿日時 - 2016-01-16 00:40:07

QNo.9111927

すぐに回答ほしいです

質問者が選んだベストアンサー

いきなり$_SESSION['user1_flag']なんてのを条件判定に使われても、
そのuser_flag1というセッションデータをどのタイミングでどんな条件でtrueにセットしているのかを
明示してくれないと、それが正しいのかどうかは私には判断できかねます。

ただ、少なくともセッションデータは、ブラウザ間で共有するデータではないので
(他人のブラウザでセットした値を参照することはできないので)
他方のブラウザの情報の入手に$_SESSIONを使おうとしているのであれば、
そのこと自体が、誤りだとは思います。
(実際にセットしている部分が不明なので、あくまでも推測ですが)

闇雲にコーディングするのではなく、きちんとロジックを組み立てたほうがよいですよ。
Web上のチャットを含めてWebアプリというのは
サーバーとクライアントとのデータのやりとりのみで
クライアントとクライアント間で通信することはできません。
このため、別のクライアントの状態を知るには、必ずサーバーを経由させる必要があります。

また、1つの変数の値を、別のクライアントに引き渡すこともできませんので
クライアント間で情報を共有するには、
サーバー上のファイルまたはデータベースを使って情報を共有させる必要があります。


よって、まずはCGI(PHP)へのアクセスのたびに、クライアントごとの
そのとき入場中の他のクライアントの情報をサーバー上のファイルに記録する
仕組みをまずは作る必要があります。
(ファイル名に自身のIPアドレスを使うなどして、他のクライアントとファイル名が衝突しないようにする)
(入場中のクライアントのIPアドレスはチャットのログデータから取り出せる)

そのうえで、チャットの閲覧処理部に

1.もし、サーバー上にクライアントの自分自身のIPアドレスがファイル名になった
上記のファイルがあれば、
そのファイルと、今現在入場中の他のクライアントを比較して
増えていれば、チャイムを鳴らすタグを入れる

2.次回のために、現在入場中のクライアントのファイルを自身のIPアドレスをファイル名にして保存する。

3.どんどんファイルが増えていくので、1日?以上経過したファイルは
ワイルドカードで削除する仕組みも入れておく。

を入れればよいでしょう。


なお、もし1対1のチャットに限定するのであれば、もっとシンプルにできます。
チャットのリロードでの閲覧処理部に
入場中が自分だけの状態から2人に変化したタイミングを
ログファイルから発見できるようにして
そこにチャイムのタグを入れればよいだけなので。

投稿日時 - 2016-01-18 00:57:21

補足

superside0様、大変お世話になりました。$_SESSION変数を皆無にし、
ほとんどの処理をファイル処理にしたところ、おおよそは、思い通りの
動作を実現できました。ありがとうございました。

投稿日時 - 2016-01-20 00:14:18

お礼

詳しいご回答、どうもありがとうございました。誤解があったことは事実です。superside0さんのご意見をしっかり踏まえたうえで、コーディングし直してみます。

投稿日時 - 2016-01-18 09:03:00

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(3)

ANo.2

> JavaScriptで、chime()関数の中身を作って、監視することになると思うのですが、どういうJavaScriptを書けばよいか皆目思いつきません。

どこまで理解されているのかわからないのと
サーバー側がどういう実装なのか分からないので、概念だけになってしまいますが…

JavaScriptは、サーバーでなくクライアント(ブラウザ)上で動作しているので
サーバからのデータをブラウザで表示が終わったあとで、
だれかが新規に入場したかを知ることはできませんので、
JavaScript”だけ”では サーバー上のデータを監視することはできません。

方法としては、

方法1.
リロード時に実行されるCGI自身で、前回の入場中のIPをクライアントごとに記録しておいて
それと比較して新規に入場したクライアントがあれば、
チャイムを鳴らすタグをCGIとして生成する。(リロード時にチャイムがなる)


方法2.
JavaScript内からサーバーに対して非同期通信(Ajax)で問い合わせし
前回と今回で入場者が増えていればチャイムを鳴らす。
これをJavaScript側でループさせる。
当然、JavaScriptからのAjaxに対して応答するCGIを別途開発する必要がある
このとき新規入場がなければ、すぐに応答しないで、入場があるまで
応答を遅らせることで、無駄な通信データを防げる。
またあたかもリアルタイムに入場を監視しているかのような状態に見える。
#これを発展させてチャットメッセージ自体もAjaxで入手すれば
#リロードを待たない応答の速いチャットとなる。


が考えられます。

投稿日時 - 2016-01-16 12:06:25

補足

superside0様のおっしゃるように、自分なりに<body>タグ以降に
リロードしたときのための、下記のPHPスクリプトをHTML内に
埋め込んだのですが、チャイムが鳴りません。
どうしたら、先に入場した人に、後から入場してきた人のページ
アクセスを知らせるチャイムを鳴動させることができるのでしょうか。
できましたら、具体的なスクリプトを書いて、ご指導お願いでき
ませんでしょうか?(ちなみにchime()関数はまだ実装しておりません。)
AJAXを利用した場合も、併記していただけると助かります。
--------------------------------------------------------
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="refresh" content="2;url=chatbody.php">
<title>チャット</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function() {
$('html,body').animate({
scrollTop: $('#last').offset().top
},'fast');
});
</script>
</head>
<body text="white" background="./image/mokume2.jpg" onLoad="chime()">
<?php
if($_SESSION['user1_flag']===true){
echo '<audio src="http://~/chat/music/schjoin.hso" autoplay></audio>';
$_SESSION['user1_flag'] = false;
}elseif($_SESSION['user2_flag']===true){
echo '<audio src="http://~/chat/music/schjoin.hso" autoplay></audio>';
$_SESSION['user2_flag'] = false;
}
?>

<div style="height: 90px;">
</div>
<div id="last"></div>
</body>
</html>

投稿日時 - 2016-01-17 01:43:37

お礼

お忙しいところ、詳しいご回答を頂き、有難うございました。

投稿日時 - 2016-01-16 13:14:11

ANo.1

(1)Aさんはチャット入場済で閲覧中
(2)Bさんのチャット入場処理

これが別々のプロセスで動いています。

(2)の処理にチャイムを鳴らすaudioタグを書いても、当然Bさんにしか聞こえません。
(1)の処理に、だれかが入場したかを監視してチャイムを鳴らす処理を入れる必要があります。

チャットの閲覧処理が、HTMLを定期的にリロードするような原始的なチャットなのか、
それともAJAXを使ったリアルタイム性のあるチャットなのか等で、
実装のアルゴリズムは異なりますが
リロード式なら、クライアントIPアドレスごとに前回閲覧時の入場中のIPを記録しておいて、
リロード時にそれと比較して増えていたらチャイムを鳴らすタグを閲覧HTMLに入れればよいでしょう。

投稿日時 - 2016-01-16 02:27:50

補足

お世話になります。
superside0様のおっしゃるようにリロード時に閲覧HTMLに<audio>タグを入れるとなると、下記のonLoad=chime() のイベント時に、JavaScriptで、chime()関数の中身を作って、監視することになると思うのですが、どういうJavaScriptを書けばよいか皆目思いつきません。具体的にどう書けばよいのかお教えいただけませんでしょうか。どうぞよろしくお願い致します。もし、JavaScriptで書かないといけないと誤解しているようでしたら、ご指導お願いできますでしょうか。
---------------------------------------------------------

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="refresh" content="2;url=chatbody.php">
<title>チャット</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function() {
$('html,body').animate({
scrollTop: $('#last').offset().top
},'fast');
});
</script>
</head>
<body text="white" background="./image/mokume2.jpg" onLoad="chime()">

<div style="height: 90px;">
</div>
<div id="last"></div>
</body>
</html>

投稿日時 - 2016-01-16 06:38:29

お礼

superside0さま、いつもお世話になっております。詳しいご回答どうもありがとうございました。おっしゃる通り実行してみますが、もしまだわからなければ、引き続きご指導よろしくお願い致します。

投稿日時 - 2016-01-16 06:18:59

-広告-
-広告-
-広告-
-広告-