0

チャットサービスを作成したいとしましょう。私の目には、物事を行うには 2 つの方法があります。皆さんが考えるより良い方法を知りたいです。または、3 番目のオプションがあるかもしれません...わかりません。

とりあえず

解決策 1:

発生した可能性のある新しいメッセージについてデータベースをチェックする間隔でサーバーにリクエストを送信する JavaScript ループがあります。データベースに新しいテキスト行を知らせるフラグがあることがわかったら、別の関数を呼び出して取得して表示します

解決策 2:

新しいエントリを待っているサーバー上のループで待機するサーバー上のメソッドへの非同期呼び出しを行い、そこに到達するとクライアントに応答を送信します。

これらの解決策のいずれかがより自然であるとは思いません。ボットは、これを行うための適切な方法を教えてくれるばかげていることを知りたいです。

ここでのポイントはチャット サービスではなく、1 人の Web ページ ユーザーからの表示入力を処理して、同じコンテンツを見ているすべてのユーザーに表示する方法です。

追加情報: クライアントで html/css/js を使用し、サーバーで php + sql を使用する予定です。

編集:私は議論を始めたくありませんでした.基本的に私は解決策1にパフォーマンスの問題があるかどうかを知りたかっただけです.それは私の範囲では受け入れられます。

4

3 に答える 3

2

状況によりますが、解決策 1 を選択する必要があると思います。私がそう考える理由については、以下をお読みください。

ソリューション 1はおそらく実装が簡単なはずです。サーバーが 1 秒あたり 65,000 を超えるリクエストを処理できる場合は、これを使用する必要があります。上。

解決策 2は、競合状態、タイムアウトのために解決策 1 の上に実装する必要があるため、実装がおそらく難しいでしょう (少なくともクライアント側ですが、サーバーをどれだけ制御できるかによってはサーバー側も同様です)。 . 利点は、正しく実行された場合、ソリューション 1 よりもはるかに効率的である可能性があることです。つまり、ポート制限に達するまでは (標準的な単一サーバーの LAMP セットアップではおそらく実行しないでしょう)。

解決策 2 に関しては、websockets を使用することもできます。これにより、クロスブラウザーの問題を犠牲にして、いくつかの問題 (正しく行うとタイムアウト) を回避し、パフォーマンスを向上させることができます。

php と何らかの形式の sql (おそらく mysql を意味すると思います) を使用すると言うように、解決策 1 を使用します。 php の歴史) では、パフォーマンスなどはあまり考えずに、やり遂げることについて考えるべきであり、その点では、解決策 1 の方が間違いなく簡単に問題なく実装できます。正しいデータベース インデックスを使用し、リクエストごとのオーバーヘッドをできるだけ低く保つようにしてください (たとえば、完全なフレームワークを開始せず、(my-)sql クエリを 1 つだけ実行します)。

すでに述べたものに加えて、サーバー送信イベントの代わりにチャンク転送を使用することもできます。さまざまなブラウザーで動作させるにはいくつかの作業が必要ですが、低遅延通信にも適しています。それ以外には、サーバーとクライアントの間に常に開いている接続があるため、ポート制限に関して websocket ソリューションと同じ欠点があります。

もう 1 つの可能性は、既製のチャット アプリケーションまたはチャット サービスを使用することです。既製のソリューションがたくさんあります。中には、パフォーマンスや機能を向上させるために独自の Web サーバーを採用しているものもあります。既製のソリューションについては、Node.JS とSocket.IO (サーバー側の JavaScript) を参照してください。サービスとしてのチャットについては、状況によって異なります。たとえば、Livechat はクライアント <-> サポート トーク用のチャット サービスを提供します。


サーバーでのスリープ/クエリループについて考えながら、より多くの人がソリューション 2 を提案する前に:

ソリューション 2 を実装する正しい方法は、スレッド間/プロセス間通信 (IPC) を使用することです。これにより、待ち時間が短縮され、リソースが節約されます。これらの例は、セマフォ、ミューテックス、または条件変数 (sem_* および pthread_* 関数) です。そうしないと、解決策 1 と同じ遅延とリソースの浪費が発生し、クロスブラウザーの問題が追加され、それをきれいに実装するための作業が増えることになります。また、その場合は、ある種の SQL ベースのデータベースとスクリプト言語の使用をやめて、よりパフォーマンスの高い言語 (C、C++、Java) に移行する必要があります。最近では、サーバー側の JavaScript でさえ、これらのタスクで php よりも優れています。ソケットを参照してください。上記のIOリンク)

于 2013-10-13T14:46:37.303 に答える
2

最初の解決策は、両側でリソースを浪費することです。WebsocketsServer-Sent イベントを見てください。 どちらもまったく新しいテクノロジですが、ブラウザとサーバーの間のその種の通信で最高のパフォーマンスが得られます。2 番目のソリューションは、ユーザーが最新のブラウザーのみを使用する必要がないため、運用環境で使用されることがあります。

于 2013-10-13T14:47:36.230 に答える
0

ソリューション 2 は、次の 2 つの理由で優れています。

  1. サーバー (およびクライアント) 側で使用するリソースが少なくなります。
  2. より反応が良いです。クライアントは、サーバーで発生したイベントをすぐに通知されますが、ソリューション 1 では、たとえば 30 秒ごとにポーリングすると、最大 30 秒の遅延でクライアントに通知できます。

サーバーが常に応答するタイムアウトを決定する必要があります。これにより、接続が失われないことが保証されます (または、クライアントが接続を失った場合、次のタイムアウトで再接続されます)。

サーバー側コードの例:

$maxtime = 30; //sec
$wait = 1000; //msec
$startTime = microtime(true);
$result = false;
do {
    $result = query_datase_for_event(); // returns false if nothing happened
    if($result) break;
    usleep($wait * 1000);
} while (microtime(true) + ($wait / 1000) - $startTime < $maxtime);
echo json_encode($result);

クライアント側のコードは、Benjamin Hutchins による Realtime Ajaxから派生させました。

于 2013-10-13T14:56:01.933 に答える