0

私はオンラインの前に多くの場所でこれに関する多くの質問を見てきましたが、約 30 のフォーラムなどのうち、どれも私が必要とする解決策を持っていませんでした。これには stackoverflow が含まれます。誰かが信頼できる解決策を見つけるのを手伝ってくれたら、大歓迎ですので、よろしくお願いします!

私の質問に答えてくれる人を助けるために、私のサイトと状況をできるだけ詳しく説明します。これが私の状況です:

私はウェブサイトを持っており、PHP と MySQL を使用しています。私の Web サイトは「非公開」の組織サイトです。人々がサイトにアクセスできるようにするために、組織の新しいメンバーと招待コードを送ります。次にユーザーが Web サイトにアクセスすると、index.php ファイルにはログイン用のフォームと登録ページへのリンクが含まれているだけです。新規メンバーは、「Register Here」リンクをクリックして登録を開始します。最初の登録ページでは、ユーザーの姓と招待コードを入力するよう求められます。これらはデータベースに対してチェックされ、その人物がリストにあり、まだ登録されていないことが確認されます。チェックに合格すると、次のページに移動し、必須情報 (ユーザー名とパスワード、電子メール アドレスなど) といくつかのオプション情報 (電話番号、経歴など) を入力します。ユーザーが有効なユーザー名とパスワードを作成し、すべての必須フィールドに入力すると、ユーザーの情報がデータベースに保存されます。パスワードはすべて適切かつ安全にソルト化およびハッシュ化されるため、問題はなく、登録プロセス全体が正常に機能します。登録後、ユーザーは index.php に戻り、作成したばかりのユーザー名とパスワードを使用してログインできるようになります。これも同様に機能します。ユーザーがログインすると、ユーザー名とパスワードがデータベースに対してチェックされ、成功した場合、ユーザーはログインされます。ユーザーがログインすると、データベースの ONLINE 値が False から True に設定されます。ユーザーはログインし、意図したとおりにサイトを使用できるようになりました。私のサイトには、(データベースの ONLINE 値に基づいて) 現在オンラインのユーザーを一覧表示する列があります。ユーザーがサイトのすべてのページにある [ログアウト] ボタンをクリックすると、logout.php スクリプトが実行され、セッションが終了し、ONLINE 値が False に戻されます。これはすべて正常に機能しますが、ユーザーが最初にログアウトせずにブラウザーを閉じると問題が発生します。これは、インターネット上のさまざまな場所でさまざまな「ソリューション」を見てきました。それらが機能しない理由と、より良い解決策が必要な理由を説明します。

私がよく目にする回答には、ある種のセッション タイムアウトまたはセッションの破棄が含まれます。実際には、ユーザーがブラウザーを閉じるとセッションが既に終了しているという事実のため、これは無関係ですが、他のユーザーにその人が現在オンラインであるかどうか。セッションが終了すると、データベースは更新されず、ユーザーは単一のインスタンスからしかログインできないため、問題が発生します。ONLINE 値がすでに TRUE に設定されているときにユーザーがログインしようとすると、ログインは許可されません。

また、オンライン値の代わりに「最後に見た」値を使用するという提案も見ました。ユーザーが過去 x 分以内にアクティビティを行っていない場合は、ユーザーをログアウトします。ただし、これは 2 つの理由で機能しません。1) そのスクリプトが機能するためには、そのスクリプトがまだどこかで実行されている必要があります。つまり、それが機能するには、別のユーザーがログインしている必要があります。つまり、この方法を使用する場合、ユーザーがブラウザーを閉じたり、接続を失ったりすると、別のユーザーがログインするまでログインし直すことができなくなります。つまり、オンラインのユーザーがいないことが何度もある可能性があります。また、別のユーザーがログインしている場合でも、接続が失われたユーザーは x 分が経過するまで再ログインできません。

onBeforeUnload JavaScript 関数を使用するというあまり頻繁ではない解決策に遭遇しましたが、ユーザーがリンクまたは「戻る」および「進む」ボタンをクリックするたびにトリガーされるという事実により、それらはほとんど確実に機能しません。また、ユーザーがブラウザで JavaScript を無効にしている場合、これはまったく機能しません。

最後に見たのは、while ループと connection_aborted 関数に関するもので、機能するように見えるのはこれだけですが、これがどのように機能するかについての非常に明確な説明は見ていません。何ヶ月もかけて実験した後、私はまだ信頼できる解決策を思い付いていません。

多くのフォーラムで、人々が「それは不可能だ」と言っているのを見てきました。私はいくつかのサイトでこれをテストし、実験しました。Facebook やフォーラムの Web サイトなどのユーザーがいるサイトには、「オンライン」ユーザーのリストがあり、ユーザーがブラウザーを閉じた場合、ユーザーの名前がリストに表示されなくなる可能性があるため、あいまいな方法でしか達成できない場合でも. したがって、誰かが解決策を知っている場合は、この件に関する知恵を共有していただければ幸いです。

4

2 に答える 2

0

それが答えです。クライアントとサーバー間の永続的な接続です。このためには、最近の websocket のような TCP 接続、またはフラッシュの古い二重接続が必要になります。これ以降、誰かが接続または切断したときに TCP が通知します。あなたがしなければならないのは、接続を追跡するだけのWebsocketサーバー(たとえば)(配列からのプッシュとポップ)と、「get_users_online」メッセージに応答する方法です。Websocket サーバー経由でユーザーのセッション (読み取り専用) にアクセスし、ユーザーがログインしているかどうかを確認できます (この方法で、セッションにニックネームを保存し、Websocket サーバーからさらにアクセスできます)。管理者 (セッション -> is_admin)。

かなり単純だと思います。

これが私が使用しているライブラリです: http://socketo.me/。symfony2 セッションをデコードするためにライブラリを使用しますが、単純なアプリケーションの場合はデコードする必要はありません (symfony2 アプリケーションはセッションをエンコードするため、websocket サーバーがそれらをデコードする必要があります)。

重要な注意: セッションは、ORM や NoSql のように (ファイル システム /tmp ではなく) 外部に保存する必要があります。

いずれにせよ、申し訳ありませんが、「最後に見た」は非常に大丈夫だと言わざるを得ません。ほとんどのサイトはこれに依存しています。あなたは何か間違っていることを理解しました。「前回」を常にチェックするために生きているサーバーを用意する必要はありません。 /admin.php?users_online=1 をリクエストするとき、「最後に見た > NOW() - 5 分」 (そのように記述しても機能しません) ので、「ONLINE」「OFFLINE」フィールドを削除することもできます。

Websocket アプローチを使用することをお勧めします。それは楽しいです。:)

幸運を!

于 2013-10-06T08:14:49.827 に答える