2

ユーザーがたくさんの友達を持つことができるコミュニティ サイトを持っています。彼のすべての友達を表示するときに、彼の友達がオンラインかオフラインかを含めたいと思います。

私の方法は、ユーザーがログインしたときにセッションを作成し、ステータス列「オンライン」でユーザーテーブルを更新することです。彼がログアウト ボタンをクリックすると、ステータスが「オフライン」に設定されます。ログアウト ボタンをクリックせずにブラウザを閉じたらどうなるでしょうか。これが私がやりたいことです:

session_start();
if (!isset($_SESSION['LAST_ACTIVITY'])) {
    // initiate value
    $_SESSION['LAST_ACTIVITY'] = time();
}
if (time() - $_SESSION['LAST_ACTIVITY'] > 3600) {
    // last activity is more than 10 minutes ago
    session_destroy();
    //direct to a php, say this user is idle and thus status = offline
    header("location: update_status.php?user=".$_SESSION['username']."&status=offline");
    // den redirect them to login page
} else {
    // update last activity timestamp
    $_SESSION['LAST_ACTIVITY'] = time();
}

これは適切な方法ですか?


編集:

ユーザーがオンラインである場合はいつでも確認し、ユーザーがページにアクセスするたびに更新する方法を示す簡単なサンプル コードを確認すると役に立ちますか?

php?user=$_SESSION['userid']すべてのリンクに含める必要がありますか?

4

9 に答える 9

5

オンライン/オフライン列だけでユーザーがログアウトしているかどうかを判断した場合、(ログアウト リンク/ボタンを押さずに) ブラウザー ウィンドウを閉じたユーザーは引き続きログインします。

ここでの通常のアプローチは、ユーザーがサイト内をいつ移動したかを追跡し、最後にページに移動した時間を保存することです。次に、ユーザーをアクティブにする定義済みの定数を設定します (たとえば、過去 15 分間にページ内をナビゲートするなど)。次に、これを SQL クエリで使用して、訪問者の友人であり、オンになっているすべてのユーザーを取得します。過去 15 分以内のサイト。

時間を日時として保存する SQL クエリ (これは MySQL のクエリです) では、次のようになります。

SELECT col1, col2, col3 FROM Users WHERE DATE_ADD(LastActive, INTERVAL 15 MINUTE) > NOW() AND UserIsFriendOfCurrentUser

もちろん、セットアップに合わせてクエリを調整する必要がありますが、うまくいけばアイデアが得られます。

于 2009-05-20T15:21:02.160 に答える
4

私の意見では、これは機能しません。ユーザーがブラウザを閉じると、ここに記述したコードが呼び出されることはありません。

可能な方法は、ユーザーがページを呼び出すたびに、ユーザーがデータベースで最後にアクティブだった時間を保存することです。ユーザーの最後のアクティビティが 5 分前よりも長かった場合、そのユーザーをオフラインとしてカウントし、これを他のユーザーに表示できます。

私はphpbb3がそのようにしていると思います...

ユーザーがブラウザを閉じたときにイベントを取得するのは負荷が高く、常に機能するとは限りません。

于 2009-05-20T15:19:36.623 に答える
2

ヘッダーの場所のリダイレクトの後に、必ず次の行を入力してください。

die();

すべてのユーザー エージェント (ブラウザー、Web スパイダーなど) がリダイレクト ヘッダーをリッスンするわけではありません。スクリプトを強制終了することが、ページの残りの部分を取得しないようにする唯一の安全な方法です。

于 2009-05-20T15:20:43.237 に答える
0

データベース セッションは、誰がオンラインで、誰がオンラインでないかを管理するのに適した方法です。理論的には、それらは自然に期限切れになるはずです。私はそれについてブログにハウツーを書きました。 /

これには、必要に応じてユーザーセッションをリモートで強制終了できるという追加のボーナスもあります:)

于 2011-12-29T18:43:59.573 に答える
0

あなたのコードにはいくつかの問題があります。

if (time() - $_SESSION['LAST_ACTIVITY'] > 3600) {
  // last activity is more than 10 minutes ago
  session_destroy();
  //direct to a php, say this user is idle and thus status = offline
  header("location: update_status.php?user=".$_SESSION['username']."&status=offline");
}

このコードでは、セッションを破棄し、破棄したセッションからユーザー名取得します。

ところで、あなたの質問が理解できたとしても、このコードでは意図した動作が得られません。

サイトにアクセスしているユーザー (開始したセッションの所有者) が 10 分以上アイドル状態になっているかどうかを確認し、そうであれば、サイトに再入ろうとしているときに切断します。

于 2009-05-20T15:20:06.933 に答える
0

私が理解している限り、あなたのソリューションは、ユーザーが最後にサイトにアクセスしたのが 10 分以上前であっても、ユーザーがまだオンラインとしてマークされていることです。

ユーザーがサイトで最後にアクティブだった時間をデータベースに保存する必要があります。ユーザーが友人のリストを見ると、今回も取得し、それが 10 分以上前のものかどうか、つまり友人が非アクティブかどうかを調べます。

于 2009-05-20T15:20:07.950 に答える
0

これを行う最善の方法は、ログインしているユーザーの活動時間を保存することです。ユーザーがページに移動するか、アクションを実行すると、データベース内の「最後のアクティビティ」の時刻が現在の時刻で更新されます。この時間がしきい値 (たとえば 15 分) を超えた場合は、ユーザーをアクティブではないと分類できます。

于 2009-05-20T15:20:20.257 に答える
0

このプロジェクトでは、次の手法を使用します。

  1. ログイン後のすべてのユーザーは、セッション ID に関連付けられています。
  2. ブラウザは、タイマーで AJAX を使用して「アクティビティ リクエスト」を送信します。
  3. 軽量のサーバー側スクリプトが DB の最後のアクティビティを更新し、セッション ID でユーザーを検索します。
  4. cronjob は、タイムアウトになったすべてのユーザーを更新してオフラインとしてマークし (実際にはセッション ID が空になります)、すべてのユーザーに対してログアウト ルーチンを実行して、ビジネス レベル レイヤーでのデータの破損を回避します。

ユーザーはどうなりますか?ユーザーがブラウザを閉じるまで - アクティビティが更新されています。ブラウザーを閉じた後、ユーザーはタイムアウトになり、オフラインとしてマークされます。ユーザーが認証を必要とする場所にアクセスしようとすると、最初にセッション ID を使用して DB でユーザーを検索し、そうでない場合は、ログイン フォーム (つまり、include(); exit();) しか表示されません。 )。

悪いことに、タブ付きブラウザーは、同じウィンドウで開かれた各タブに対して同じセッション ID を使用します。しかし、私たちのプロジェクトはゲームであり、1 つのブラウザーからのマルチユーザーは許可されていません。実際には、2 人以上のユーザーが 1 つのブラウザーの異なるタブからログインしようとすることは非常にまれな状況です...

于 2009-05-20T16:11:31.997 に答える
0

$_SESSION最後のアクティビティ時間の保存には使用しないでください。last_activityユーザーがページに移動するたびに、users テーブルの現在の時刻で呼び出された列を更新します。

<?php
session_start();

$userId = (int)$_SESSION['user']; // make sure it's an integer
$db->exec('
    UPDATE users 
    SET last_activity = NOW() 
    WHERE id = ' . $_SESSION['id']
);
//...

友達のリストを取得したら、if ステートメントを追加して、友達がオンラインかどうかを確認します (これは MySQL のバージョンです)。

SELECT 
    u.user_name, u.name, etc,
    IF(
        UNIX_TIMESTAMP() - UNIX_TIMESTAMP(u.last_activity) < 300, 
        1, 0
    ) as online
    ... 

300 は秒なので 5 分です。必要に応じてこれを調整します。次に、次のように友達にアクセスできます。

$friends = $db->query(/* above SQL */);
foreach($friends as $friend)
{
    if($friend['online'] == 1)
        // online specific stuff
    else
        // offline specific stuff
}
于 2009-05-20T21:53:42.727 に答える