5

jquery ajaxを使用して定期的なポーリング(15秒ごと)を使用して新しいメッセージをチェックする、ある種のチャット/フォーラムアプリケーションがあります。私は、すべて同じアプリケーションを指している、多くのタブを備えたいくつかの同じブラウザー インスタンスをロードすることで、「おかしなこと」をしようとするユーザーの問題を回避できるかどうか疑問に思っていました。各タブは ajax リクエストを送信しているため、複数のユーザーが同じことを始めた場合、サーバーがオーバーフローする可能性があります。

セッションをテーブルに保存し、最終アクセス時刻と IP アドレスも一緒に保存します。これは、ユーザーが同じブラウザーを使用しない限り問題なく機能します。ajax POST または GET リクエストを使用して送信された一意の識別子を保存できますが、通常の (悪用していない) ユーザーがページを更新すると問題が発生し、新しい識別子が作成されます。

これはまだ本当の問題ではありませんが、誰かがこのようなシステムの悪用を考える前に見つけたほうがよいでしょう :) これを行う方法はありますか?

4

4 に答える 4

2

1 つのオプションは、次のようにデータをフェッチすることです。

  • スクリプトはデータをポーリングする準備をしています。リクエストを実行する前に、データをフェッチすることを示す値を ( LocalStorageを使用して) 書き込みます。localStorage.setItem("last-request-timestamp", new Date().getTime());
  • データをポーリングします。結果が得られます。その結果を localStorage に書き込みます。localStorage.setItem("latest-messages", ajax_result);
  • localStorage.getItem("last-request-timestamp")が 15 秒以上前かどうかを確認して、ページがデータをポーリングする準備をしているかどうかを確認します。そうである場合は、手順 1 に進みます。そうでない場合は、15 秒待ってからもう一度確認してください。
  • 現在のページがデータをポーリングしたかどうかに関係なく、latest-messages変数を確認してページを更新します。

もちろん、他のページは localStorage データを共有します。現時点で別のページがフェッチされている場合、データは取得されません。ページ #1 が閉じられると、他のページの 1 つが引き続きデータをフェッチします。

以前に LocalStorage を使用したことはありませんが、ブラウザーのサポートは十分に機能しているようです。キーと値の配列として使用することもできるはずです: localStorage["last-request-timestamp"].

文字列は localStorage にしか格納できませんが、もちろん JSON にシリアル化できます。

于 2012-07-12T16:29:50.983 に答える
0

JavaScriptで実行できるかどうかはわかりません。タブがアクティブかどうかを確認できます。そして、アクティブなタブでのみ ajax を実行しますか?

于 2012-07-12T00:48:09.863 に答える
0

問題に Memcached/Redis のようなものを投げてみませんか? 10 ~ 15 秒の有効期間で応答をキャッシュし、できるだけ多くの処理を回避します。

于 2012-07-12T17:12:09.167 に答える
0

同様の問題があります。ここで、すべてのユーザーにログインを強制します (つまり、ユーザーの電子メールを持っていることを意味します)。また、アカウントごとの接続制限と接続ごとのリクエスト制限を設定し、5 回のオーバーフローの後、ユーザーにキャプチャを入力するように依頼し、30 分間アカウントをブロックし、パスワード回復リンクを含む電子メールを送信します。それは明確な解決策ではありませんが、今のところ私にとってはうまくいきます。

更新:

これを行う最も簡単な方法は、Cookie またはセッション ストレージを使用することです。クッキーを使用しています。アルゴリズムは単純です。

  1. Web でのユーザー ログイン。
  2. このユーザーに対して開いているセッションがあるかどうかを確認し、開いてから、他のセッションを削除するか、例外をトリガーするか、そのセッションに切り替えます。目的の動作を独自に決定しました。
  3. ユーザーのセッション ID を作成し、データベースに保存します。
  4. 特定のユーザーが開いているセッションを検出するためのセッション カウンター フィールドを増やします。これにより、使用中のブラウザーが 1 つであろうと多数であろうと問題になりません。
  5. 最後のアクセス マークを更新します (私はmicrotime(true) + $delaymysql を使用し ますdecimal(14,4))。ユーザーに送信する
  6. IDをクライアントに送信

リクエストごとに:

  1. $_COOKIE に渡された ID でセッションを検索します。
  2. 最終アクセスマークを確認してください。それ以下の場合microtime(true)は、クライアントがリクエストを頻繁に送信することを意味するため、何をすべきかを自分で決定します。たとえば、マークを増やすか、microtime(true) + $delay + $penaltyセッション全体をドロップするか、エラーをトリガーします。動作はアプリケーションによって異なります。
于 2012-07-11T23:30:34.247 に答える