質問

私が現在取り組んでいるプロジェクトでは、Web チャット アプリケーションを開発する必要があります。これは非常に複雑なチャットではなく、2 人を結び付けて特定のトピックについて話すための単なる方法であり、いかなる種類の認証も必要ありません。 2 人のユーザーのうちの 1 人については、絵文字やアバターなどをサポートする必要はありません。

プロジェクト メンバーの何人かが、BOSH 経由で XMPP を使用できるのではないかと提案しました。私は、それは船の網で魚を捕まえようとするようなものだと言い、単純な Ajax/MySQL Web チャットのような、より単純な方法を提案しましたが、パフォーマンスが心配です。同時に開いている多数のチャットを継続的にポーリングするため、サーバーでヒットします。

誰かがこれまでにこのようなことをしたことがありますか?あなたは何をお勧めします?

役に立ちましたか?

解決

こちらも検討してみてはいかがでしょうか 彗星.

GTalk、Meebo、その他多くの企業で使用されています 他のチャットアプリケーション. 。私がそれを実験していた数年前には、それを実装するためのライブラリやサーバー アーキテクチャに関する詳細はあまりありませんでしたが、現在はさらに多くのものがあるようです。

を見てください。 彗星 詳細な技術情報については、プロジェクトを参照してください。

他のヒント

あなたは何をお勧めします?

BOSH を介した XMPP

他の人が独自のメッセージ形式やトランスポート プロトコルを発明する必要はありません。試してみると、徐々に BOSH と同じくらい複雑になりますが、サードパーティのライブラリのサポートや標準化の恩恵は受けられません。

HTTP ポーリングのアイデアが気に入らない場合は、サーバー上のデーモンに常時接続する Flash ムービーをチャット ページに置くことができます。その場合、Flash ムービーはクライアント上で JavaScript 関数を呼び出して更新します。新しいメッセージが来るとチャットします。(チャットに Flash インターフェイスが必要な場合を除きます。)

Comet についても調べてみるのもいいかもしれません。

誰もがこの種のことに Cometd を使用していると思いました。

BOSH は、HTTP 経由で XMPP を転送するための標準です。データをクライアントにプッシュするために Comet が関与します。

サーバーからブラウザーにプッシュされるメッセージを処理するための非常に優れたサーバーがあります ( 彗星) - 軌道上. 。memcached と同様に、他のテクノロジー (Django、Rails、PHP など) と簡単に統合できます。

重大な負荷を処理したい場合は、必ずチェックする必要があります。それ以外の場合は、単純な Ajax ポーリングが最良の方法です。

重要なのは、アプリがサーバー上の CGI を呼び出す必要があるのは、誰かが何かを言ったときだけだということを理解することです。通常のポーリングでは、新しいチャットがあるたびに CGI スクリプトが更新する静的ページをポーリングします。HEAD リクエストを使用し、タイムスタンプを最後に確認されたものと比較し、タイムスタンプが変更された場合にのみ完全な GET を実行します。この方法で単純な単純なチャット アプリケーションを実装しましたが、負荷と帯域幅の使用量は、数十人の同時ユーザーにとっては無視できます。

私も数か月前にこれとまったく同じことをしましたが、コンセプトをいじって楽しんでいたのです。実際に使ってみたのは、 永遠のフレーム 投票の代わりにテクニックを使用します。

以下のコードは、「パーティー チャット」設定を取得するために必要な一般概念を含む私の「comet」js ファイルです。

function Comet(key) {

  var random = key;
  var title = 'Comet';
  var connection = false;
  var iframediv = false;
  var browserIsIE = /*@cc_on!@*/false;
  var blurStatus = false;
  var tmpframe = document.createElement('iframe');
  var nl = '\r\n';

  this.initialize = function() {
    if (browserIsIE) {
      connection = new ActiveXObject("htmlfile");
      connection.open();
      connection.write("<html>");
      connection.write("<script>document.domain = '"+document.domain+"'");
      connection.write("</html>");
      connection.close();
      iframediv = connection.createElement("div");
      connection.appendChild(iframediv);
      connection.parentWindow.comet = comet;
      iframediv.innerHTML = "<iframe id='comet_iframe' src='./comet.aspx?key="+random+"'></iframe>";
    } else {
      connection = document.createElement('iframe');
      connection.setAttribute('id', 'comet_iframe');
      iframediv = document.createElement('iframe');
      iframediv.setAttribute('src', './comet.aspx?key='+random);
      connection.appendChild(iframediv);
      document.body.appendChild(connection);
    }
  }

  // this function is called from the server to keep the connection alive
  this.keepAlive = function () {
    if (!browserIsIE) {
        mozillaHack();
    }
  }

  // this function is called from the server to update the client
  this.updateClient = function (value) {
    var outputDiv = document.getElementById('output');
    outputDiv.value = value + nl + outputDiv.value;
    if (blurStatus == true) {
        document.title = value;
    }
    if (!browserIsIE) {
        mozillaHack();
    }
  }

  this.onUnload = function() {
    if (connection) {
      // this will release the iframe to prevent problems with IE when reloading the page
      connection = false;
    }
  }

  this.toggleBlurStatus = function(bool) {
    blurStatus = bool;
  }

  this.resetTitle = function() {
    document.title = title;
  }

  function mozillaHack() {
    // this hack will fix the hour glass and loading status for Mozilla browsers
    document.body.appendChild(tmpframe);
    document.body.removeChild(tmpframe);
  }
}

誰もがこの種のことに Cometd を使用していると思いました。

私もジョンの意見に同意します。しかし、答えられない別の質問がありました。
私はこれを実行しましたが、データベースを使用する代わりにフラット ファイルを使用したため、最終的にサーバーが機能不全に陥りましたが、アクティブ ユーザーが約 450 人になるまではそうではありませんでした。データベースを使用して実行していれば、おそらくうまくいかなかったでしょう。より良い。
これは、Godaddy の基本的なホスティング アカウントで行われました。

編集:ところで、私が電話を受けたとき、ゴダディはあまり面白くないようでした。

ポーリングが最も簡単なアプローチだと思いますので、最初にそれをお勧めします。負荷が問題になる場合は、より複雑な手法を検討してください。長所と短所についての良い議論はここにあります -http://www.infoq.com/news/2007/07/pushvspull
http://ajaxian.com/archives/a-report-on-push-versus-pull

チェックアウト スピーク. 。それは オープンソース ソリューション バックグラウンドで BOSH と XMPP を使用する Web ベースのチャット ルーム向け。

この投稿を見つけました。古いものですが、投票の概念は多くの人に問題を引き起こしています。そこで実装例をここに載せておきます。しかし、それをあなたに与える前に、少し前に私を怒らせたアドバイスをしておく必要があります。

ポーリングするときは、セッションの動作に注意する必要があります (競合状態)。簡単に説明すると、次のようになります。セッションを開くと、2 つのスレッドが異なるデータを書き込むのを避けるために、セッションが閉じるまでセッション ファイルはロックされます。したがって、ユーザーがログに記録されているかどうかを確認するためにセッションが必要な場合は、ポーリングする前に必ずセッションを閉じてください。

私のデモでは、PHP でのポーリング実装の例を示します。データベースではなく、代わりにファイルを使用します。ポーリング ボタンをクリックするとループに入り、ファイルが変更されるまでポーリングが継続します。フォームに記入して「リリース」をクリックすると、入力した内容がファイルに保存されます。ファイルの変更時刻が変更されるため、ポーリングは停止します。

ヒント:のようなツールを使用します ファイアバグ 何が起こったのかを見るために。

では、私の英語よりも良い言語で話してみましょう。

<?php

    // For this demo
    if (file_exists('poll.txt') == false) {
        file_put_contents('poll.txt', '');
    }

    if (isset($_GET['poll'])) {

        // Don't forget to change the default time limit
        set_time_limit(120);

        date_default_timezone_set('Europe/Paris');
        $time = time();

        // We loop until you click on the "release" button...
        $poll = true;
        $number_of_tries = 1;
        while ($poll)
        {
            // Here we simulate a request (last mtime of file could be a creation/update_date field on a base)
            clearstatcache();
            $mtime = filemtime('poll.txt');

            if ($mtime > $time) {
                $result = htmlentities(file_get_contents('poll.txt'));
                $poll = false;
            }

            // Of course, else your polling will kill your resources!
            $number_of_tries++;
            sleep(1);
        }

        // Outputs result
        echo "Number of tries : {$number_of_tries}<br/>{$result}";
        die();
    }

    // Here we catch the release form
    if (isset($_GET['release']))
    {
        $data = '';
        if (isset($_GET['data'])) {
            $data = $_GET['data'];
        }
        file_put_contents('poll.txt', $data);
        die();
    }

?>

<!-- click this button to begin long-polling -->
<input id="poll" type="button" value="Click me to start polling" />

<br/><br/>

Give me some text here :
<br/>
<input id="data" type="text" />
<br/>

<!-- click this button to release long-polling -->
<input id="release" type="button" value="Click me to release polling" disabled="disabled" />

<br/><br/>

Result after releasing polling :
<div id="result"></div>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">

// Script to launch polling
$('#poll').click(function() {
    $('#poll').attr('disabled', 'disabled');
    $('#release').removeAttr('disabled');
    $.ajax({
        url: 'poll.php',
        data: {
            poll: 'yes' // sets our $_GET['poll']
        },
        success: function(data) {
            $('#result').html(data);
            $('#poll').removeAttr('disabled');
            $('#release').attr('disabled', 'disabled');
        }
    });
});

// Script to release polling
$('#release').click(function() {
    $.ajax({
        url: 'poll.php',
        data: {
            release: 'yes', // sets our $_GET['release']
            data: $('#data').val() // sets our $_GET['data']
        }
    });
});

</script>

あなたはそれを試すことができます ここ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top