4

こんにちは、私は部分的に動作するコードを持っています。しかし、私はそれにも問題があります。しかし、私が達成しようとしていることをお話ししましょう...私のサイトには、ユーザーがログインしている場合にのみ、すべてのユーザーを一度だけホームページに送信するログイン機能があります。他に誰を表示したいですかリストにユーザー名が表示されているページにログインしています。

私のコードの現在の能力...

わかりましたので、サイトに参加するユーザーをデータベースに追加し、そのデータベースの各ユーザーを div に表示するようにコーディングできます。これは、すべての人をオンラインで表示するのに最適です...

問題はどこにあるのか...

ただし、ユーザーがそのページを離れた場合、オンライン ユーザー データベースからユーザー名を削除する必要があります。以前は、Java の on window close オプションを使用して単純にこれを行っていました。しかし、Google サファリと Firefox がこのオプションをサポートしなくなったため、別の方法を探す必要があります。

コードベローは何をしますか...

したがって、次のコードは間隔をロードするため、かなりの時間が経過すると、その中のコードが繰り返されます。このコードは、最初にユーザーをデータベースに追加し、次にそのユーザーをサイトのリストに表示し、ユーザーがオフラインになる場合に備えてデータベースからユーザーを削除します。

問題はどこにあるのか...

これは 1 人のユーザーにとっては非常にうまくいっていますが、2 番目のユーザーが関与すると、間隔が別の時間に落ちます。そのため、リストが表示された後にデータベースからユーザーを削除しましたが、2 番目のユーザーがデータベースを表示し、最初のユーザーが削除されたためデータベースに含まれていないことを意味します...これにより、ユーザーがオフラインになった場合にも問題が発生します関数が途中で実行されると、それらはデータベースに残り、データベースからそれらを削除することはできません。

以下はJavaコードです...

    $(document).ready(function() {
   
var user_name = "<?php print $username ?>";

setInterval(function() {

       $.post('onlineusers.php', { name: user_name, action:"joined" }); 

       $.post("onlineusers.php", { action2: "list" }, function(data){
       $('#listusers').html(data);
       });

       $.post("onlineusers.php", { nameleft: user_name, action3:"left" }, function(data){
       $('#errorrreport').html(data);
       });

}, 5000);
           
    }):  
    

これで、PHP ドキュメント コードが作成されました。

    //------------User joined page put into database --------  
if( $_REQUEST["name"])
{
  $user_name = $_REQUEST['name'];
};  

if( $_REQUEST["action"])
{
  $action = $_REQUEST['action'];  
};

if ($action == 'joined') {
  user_joined($user_name);   
};

//-----------Listing online users within page -------------  
 if( $_REQUEST["action2"])
{
  $action2 = $_REQUEST['action2'];

};

if($action2 == 'list') {

foreach (user_list() as $user){
       echo $user . "<br />";  
      
};
};

//------------ User left delete from the database ------------
if( $_REQUEST["nameleft"])
{
  $user_nameleft = $_REQUEST['nameleft'];

};  

if( $_REQUEST["action3"]){
  $action3 = $_REQUEST['action3'];
};

if($action3 == 'left') {
  user_left($user_nameleft); 
};        



//------ Functions what to do... --------

    function user_joined($user_name) {
  $user_name = mysql_real_escape_string(htmlentities($user_name));
  mysql_query("INSERT INTO users (user_name)VALUES('$user_name')") or die("this didn't happen");
   
}

function user_left($user_nameleft) {
  $user_name = mysql_real_escape_string(($user_nameleft));
  $query = mysql_query("DELETE FROM users WHERE user_name = '$user_nameleft'")or die("failed to delete from table");

}

function user_list() {
  $user_list = array();
  $users_query = mysql_query("SELECT user_name FROM users") or die ("Unable to collect userlist");
  
while ($users_row = mysql_fetch_assoc($users_query)){
  $user_list[] = $users_row['user_name'];

}  
   
  return $user_list;

}

上記のコード

申し訳ありませんが、機能させるために何度も再コーディングしたため、少し面倒です。これを機能させるために誰かが私に何か助けてくれれば幸いです。上記のコードだけでは簡単ではない場合は、ページへの入り口でユーザーをオンライン ユーザー データベースに追加し、データベース上のユーザーのリストから頻繁にオンラインになっているユーザーをリストすることができます。

本当の問題と私があなたの助けを求めているところ...

ただし、次のコードについて何か考えがあれば、それは素晴らしいことです...ユーザーがページを離れると、問題が発生します。ユーザーがまだアクティブであることを確認する方法が必要です。ユーザーがデータベースから削除されていない場合は、リストが更新されたときにユーザーがリストに表示されなくなります。応答がなくなり、データベースからユーザーを削除するまで、何かにpingを実行するなど。

私の現在のコードには複数のユーザーと間隔関数の同期に問題があるため、さまざまなユーザーがさまざまな時間にリストの更新を見ることを考慮する必要があります。

PS私は$ SESSIONの使用も検討しましたが、オフラインユーザーをチェックしてデータベースから削除することでこれを機能させる方法はまだわかりません。これはそれを行う方法かもしれません。

ありがとう、私は続けるのに十分な情報があることを願っています。

4

2 に答える 2

2

私は別のアプローチを取りました:
JS:
5 秒のループ、AJAX は onlinenow.php を要求し、返された html をオンライン ユーザー ボックスに表示します - これは主に W3C からコピーして URL を変更して貼り付けたものです。

setInterval("getOnline()",5000);
function getOnline()
{
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("onlineNow").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","http://www.path.com/to/onlinenow.php",true);
xmlhttp.send();
}

PHP:
user/ip/identifier を取得し、その + unix タイムスタンプを DB に保存/更新します 過去 10 分間の unix タイムスタンプを持つすべての行のリストを返します

<?php
header('Access-Control-Allow-Origin: *');//Pretty sure this enables cross domain AJAX
$session = $_SERVER['REMOTE_ADDR'];
$time=time();
$time_check=$time-60; //SET TIME 10 Minute


$host="localhost"; // Host name
$username="root"; // Mysql username
$password="pass"; // Mysql password
$db_name="custom"; // Database name
$tbl_name="table"; // Table name


// Connect to server and select databse
 mysql_connect("$host", "$username", "$password")or die("cannot connect to server");
 mysql_select_db("$db_name")or die("cannot select DB");

// Check if user is already in the DB
$sql="SELECT * FROM $tbl_name WHERE session='$session'";
 $result=mysql_query($sql);

$count=mysql_num_rows($result);

if($count=="0"){
    //User is not in the DB, lets add them
$sql1="INSERT INTO $tbl_name(session, time, ip)VALUES('$session', '$time', '".$_SERVER['REMOTE_ADDR']."')";
$result1=mysql_query($sql1);
}
//Update this user's entry
else {
    //User is in the DB, Update their entry
    $sql2="UPDATE $tbl_name SET time='$time' WHERE session = '$session'";
    $result2=mysql_query($sql2);
}

//Done updating info, time to get the user list
// if over 10 minute, delete session - Could just get all in past 10 mins instead
$sql4="DELETE FROM $tbl_name WHERE time<$time_check";
$result4=mysql_query($sql4);

//Get total users (Could get a list of names if you preferred and store the info)
$sql3="SELECT * FROM $tbl_name";
$result3=mysql_query($sql3);
$count_user_online=mysql_num_rows($result3);
if ($count_user_online == 1) {
    $plur = "";
}
else {
    $plur = "s";
}
echo "&nbsp;&nbsp;$count_user_online user".$plur." online now&nbsp;&nbsp;";

// Close connection 
mysql_close();
 ?>

ユーザー名を表示する場合と表示しない場合で、このロジックを数回使用しました (数字のみの場合もあります)。
もちろん、コードは改善される可能性がありますが、基本原則はかなり優れたソリューションです。

于 2013-09-16T15:01:21.443 に答える
0

削除する代わりに、挿入時にタイムスタンプ (サーバーベース) を含めることができます。

次に、JavaScriptコードを1分ごとに挿入/更新します。

次に、誰がオンになっているかのクエリは、最近のタイムスタンプを持つ行 (最後の 65 秒など) です。

もちろん、これまでに誰がいつ参加したかのログが必要でない限り、最終的にはテーブルの古い行を消去する必要があります。

于 2013-09-16T15:01:37.063 に答える