4

複数の訪問者がhttp://site.com/chat.phpに接続します

各自がテキスト メッセージを書いて chat.php に送信すると、全員のブラウザ ( http://site.com/chat.php )に即座に表示されます。

データベースを使用する必要がありますか? つまり、AJAX または PHP のバッファ機能は、セッションのチャット ルームに十分ですか?

異なるユーザーのセッションが互いにデータを共有するにはどうすればよいですか?

アイデアや洞察をいただければ幸いです。

編集:リンクをありがとう。しかし、私が欲しいのは、データをクライアント ブラウザーにプッシュする方法です。クライアント ブラウザ (AJAX であろうとなかろうと) を常に更新することが唯一の方法ですか? また、ここでの課題は、たとえば 2 人、1 対 1 など、さまざまなユーザーがチャット テキストを共有する方法です。それらをどのように保管しますか?また、2 つのクライアント間でテキストをどのように同期しますか? 好ましくはデータベースを使用しない。

編集 2: 実際、Peter D が言及したYShoutは、この仕事をかなりうまく行っています。ブラウザを更新し続けていないようです。しかし、新しいメッセージを既存のユーザーのウィンドウにプッシュする方法がわかりません。

4

5 に答える 5

18

チャット アプリケーションを作成するには、(大まかに) 3 つのオプションがあります。

ソケット

フロントエンドには flash/java とソケットを使用し、バックエンドにはソケット対応のプログラミング言語を使用します。バックエンドには、マルチスレッドで NIO に対応しているため、java または python をお勧めします。PHP でそれを行うことは可能です (ただし、php は実際には効率的なマルチスレッド化を行うことができず、一般的にこれにはあまり適していません)。これは、高性能が必要な場合のオプションであり、おそらく探しているものではありません。

ajax と pull を使用する

この場合、何か新しいことが起こった場合、すべてのクライアントが常に (たとえば 2 秒ごとに) ポーリングしています。その間隔でしか応答が得られないので、奇妙に感じます。さらに、サーバーと帯域幅にかなりの負担がかかります. ブラウザは常に更新されるため、アプリケーションがこの手法を使用していることはご存知でしょう。これは次善の解決策です。

ajax を使用してプッシュする

これは multipart-responses で動作し、バックエンドで実行時間の長い (php-) スクリプトがあります。最善の解決策ではありませんが、ほとんどの場合、引っ張るよりも優れており、機能し、いくつかの有名なチャット アプリで使用されています。この手法はCOMETと呼ばれることもあります。

私のアドバイス: 実稼働用のチャット アプリが必要な場合は、既存のものをインストールしてください。チャット アプリケーションのプログラミングはそれほど簡単はありません。

単に学習したい場合は、単純な ajax/pull アプリから始めてから、ajax と push を使用してプログラムを作成してみてください。

はい、おそらくデータベースが必要になるでしょう。テキスト ファイルで動作する非常に単純な ajax/pull ソリューションを楽しみながら実装することに成功しました (ただし、本番環境では使用しません!)。

サーバー側のバックエンドなしで (フロントエンドの JavaScript だけで) チャット アプリを作成することは (私の知る限りではありますが、かなり確信しています) 不可能です!

アップデート

データのプッシュがどのように行われるかを知りたい場合は、次のソースを参照してください: http://wehrlos.strain.at/httpreq/client.html。非同期マルチパートはあなたが望むものです:)

function asSendSyncMulti() {
    var httpReq = new XMLHttpRequest();

    showMessage( 'Sending Sync Multipart ' + (++this.reqCount)  );

    // Sync - wait until data arrives
    httpReq.multipart   = true;     
    httpReq.open( 'GET', 'server.php?multipart=true&c=' + (this.reqCount), false );
    httpReq.onload = showReq;
    httpReq.send( null );
}

function showReq( event ) {
    if ( event.target.readyState == 4 ) {
        showMessage( 'Data arrives: ' + event.target.responseText );
    }
    else {
        alert( 'an error occured: ' + event.target.readyState );
    }

}

showReq は、通常の ajax リクエストのように 1 回だけではなく、データが到着するたびに呼び出されます (ここでは jquery やプロトタイプを使用していないため、コードは少し太っています - これは本当に古いです :))。

サーバー側の部分は次のとおりです。

<?php

    $c = $_GET[ 'c' ];

    header('Content-type: multipart/x-mixed-replace;boundary="rn9012"');

    sleep( 1 );

    print "--rn9012\n";
    print "Content-type: application/xml\n\n";
    print "\n";
    print "Multipart: First Part of Request " . $c . "\n";
    print "--rn9012\n";
    flush();

    sleep( 3 );

    print "Content-type: application/xml\n\n";
    print "\n";
    print "Multipart: Second Part of Request " . $c . "\n";
    print "--rn9012--\n";

?>

update2

データベースに関して: バックエンドにmod_php /cgi のような非共有アーキテクチャがある場合、データベースやテキストファイルなどの何らかの外部ストレージが必要になることは間違いありません。ただし、独自の http サーバーを作成することでメモリに依存することができます (php では可能ですが、深刻な作業にはお勧めしません)。それはそれほど複雑ではありませんが、おそらくあなたの質問の範囲外です^^

update3

私はミスを犯した!私が実際にそのようなことをしたのは久しぶりなので、すべてが混乱しました。ここに修正があります:

  1. マルチパート応答は mozilla ブラウザーでのみ機能するため、使用が制限されます。COMET はマルチパート レスポンスを意味するものではありません。

  2. COMET の意味: 従来のシングルパート応答ですが、データが利用可能になるまで (無限ループとスリープで) 保持されます。そのため、ブラウザーは (最悪の場合) すべてのアクションに対して 1 つの要求/応答を持ち、応答に値するものが何も起こらなくても、x 秒ごとに 1 つの要求ではありません。

于 2009-04-21T13:47:15.290 に答える
4

DBなしで、クライアントが更新のためにサーバーをポーリングせずに、これを機能させたいと述べています。

理論的には、チャットの「ログ」をサーバー上のテキスト ファイルに保存し、ユーザーが chat.php ページで GET 要求を行うようにページを変更することでこれを行うことができますが、PHP ページは実際には返信を終了しません。ユーザーに。(たとえば、応答が完了しない)

メッセージがないときに接続を維持するには、 「 no op 」データを送り返す必要がありますが、理論的にはこれでうまくいきます。

問題は、上記を達成するのにまだ多くの作業が必要なことです。新しいコメントを送信するには、AJAX ポストをサーバーに戻す必要があります... ユーザーのブラウザーはずっと回転しています (チャットログを iframe にネストしない限り - たとえば、より多くの作業)...そしてこの種のセットアップの管理は非常に困難です。

他の場所から無料のチャット スクリプトを取得することをお勧めします (例: http://tinychat.com/ )。または、(楽しみ/経験のために) 自分で作成したい場合は、先に進みますが、DB から始めて、サーバーからメッセージをプッシュおよびプルします。

最後に、AJAX リクエストでサーバーを「叩く」ことを心配している場合は、心配しないでください。チャットを構築するだけで、パフォーマンスの問題が見つかった場合は、アクティビティがないときに何百ものリクエストがチャットに殺到しないように最適化する方法についての質問とともに StackOverflow に戻ります。

于 2009-04-21T13:32:07.370 に答える
2

HTTP は簡単にプッシュできるようにはできていませんが、PHP スクリプトを決して終了させず、JavaScript の結果を注意深く監視することで、プッシュ接続をエミュレートできます。

基本的に、ストリーム リーダーをシミュレートしています。

于 2009-04-21T13:49:19.467 に答える
1

新規ユーザーが部屋に入る前に発生したチャットの履歴をロードする場合は、DBまたはその他のストレージが必要です。学習用のチャットを作成しようとしているのでない限り、無料で使用するにはあまりにも多くのことがあります。

http://tinychat.comは別のシンプルなチャットサイトです。

AJAXは正常に動作します。自分のサイトの1つに簡単なページを作成しました。しかし、チャットは思ったほど頻繁には使用されないことがわかりました。

データの共有はもう少し複雑になり、IRCサーバーをホストし、ユーザーがデータ交換機能を備えたIRCクライアントを使用できるようにすることで、より簡単に実行できるようになります。1人のユーザーがサイトにアップロードするのを妨げるものは何もありませんが、他のユーザーはダウンロードします。ユーザーは互いに接続されていないため、Webインターフェイスを使用するのは人から人への困難です。

于 2009-04-21T13:10:59.637 に答える
1

PubNubのようなサービスを使用して、HTML と Javascript でこれを完全に行うことができます。履歴 APIのようなものを使用して最後の x チャット メッセージを入力できるため、データベースは必要ありません。

これは、PubNub を使用してチャット アプリを構築するための簡単なチュートリアルです。

10 行のコードによるリアルタイム チャット アプリ

ここに画像の説明を入力

Enter Chat and press enter
<div><input id=input placeholder=you-chat-here /></div>

Chat Output
<div id=box></div>

<script src=http://cdn.pubnub.com/pubnub.min.js></script>
<script>(function(){
var box = PUBNUB.$('box'), input = PUBNUB.$('input'), channel = 'chat';
PUBNUB.subscribe({
    channel  : channel,
    callback : function(text) { box.innerHTML = (''+text).replace( /[<>]/g, '' ) + '<br>' + box.innerHTML }
});
PUBNUB.bind( 'keyup', input, function(e) {
    (e.keyCode || e.charCode) === 13 && PUBNUB.publish({
        channel : channel, message : input.value, x : (input.value='')
    })
} )
})()</script>
于 2014-02-15T00:01:00.033 に答える