他のメッセージングプロトコル ( XMPP STOMPまたはMemcache(MemcacheQ))とは異なり、AMQPには柔軟性があります。
AMQPの基本に戻って少し理論。 詳細については、<a href= first habrahabr.ru/blogs/webdev/62502 "title"AMQPを使用する練習>>こちら
公開は 、個々のExchange (Exchange)でメッセージ (Message)を転送することにより実行されます
コンシューマーは個々のキューからメッセージを読み取ります
バインドを使用して、キューとExchangeはルーティングキーシステムを介して通信されます。
Exchangeへのメッセージの各パブリケーションには、対応するキューに送信されるルートキーが付随します。 Exchangeには、funout、direct、topicの3つのタイプがあります。 キーパターンに従ってメッセージをキューに分散できるため、後者が必要です。
チャットを実装するには、各チャットルームに独自のExchangeが必要です。 同じ名前の交換の名前を持つphp、mysql、hiloadの3つのチャットルームを開いてみましょう。
PHP AMQP APIに戻った場合、PHPテーマでチャットを初期化するときに、交換を宣言する必要があります。
// exchange declare exchange.php
$rabbit = new Rabbit(); // connection
$rabbit->exchange('php', "topic"); // declade exchange
交換のタイプは、キーパターンに従ってルーティングを使用することになっているため、トピック(トピック)である必要があります(これをさらに解読します)。
ユーザーがチャット(ユーザーのセッションの登録)に入ると、彼は同時に購読者であり、広報担当者でもあります。メッセージを表示する必要がありますよね?
したがって、着信メッセージのキューを宣言する必要があります。 チャット参加者ごとに順番があり、複数のチャットルームに同時に参加している場合は、チャットルームごとに順番があります。
原則として、WEBで永続的な長期接続を維持できる場合、チャットごとに1つのキューで十分です。 これは、ICQやメールエージェントなどの個別のチャットクライアントを作成する場合に現実的です。接続を開き、要求を送信し、任意の数のイベントを待機し、アラートを取得し、応答を送信し、接続を閉じます。 しかし、HTTPを介して交換を組織する場合、交換の非同期的な性質が想定されます。接続を開き、要求を送信し、応答を受信し、空の接続も受信し、接続を閉じました。
チャットに登録するときに、キューを宣言します。
// login.php
$rabbit = new Rabbit(); // connection
$rabbit->queue('php.fanat', AMQP_DURABLE); // declade queue
AMQP_DURABLE-AMQPブローカーの再起動時のメッセージをデータベースに保存する必要があることを示すフラグ
fanat氏がmysqlチャットに同時に参加したい場合は、新しいキューを宣言する必要があります。
$ rabbit-> queue( 'mysql.fanat'、AMQP_DURABLE);
次のステップは、php.fanatキューをphp exchangeにバインドすることです。
$rabbit-> bind( 'php', 'php.fanat', 'fanat' ); // binding exchange to queue where routing_key
また、各参加者のクライアント側で行われます。
チャットに3人の参加者がいるとします:fanat、fisher、fixxxer。 たとえば、参加者であるfanatからメッセージを公開するには、コードを実行する必要があります。//
// sendMessage.php
$rabbit = new Rabbit(); // connection
$msg = " ";
$rabbit->publish('php','*',$msg); //
// sendMessage.php
$rabbit = new Rabbit(); // connection
$msg = " ";
$rabbit->publish('php','*',$msg); //
この命令は、「php」とキー「*」の交換を公開します。 交換のタイプは「トピック」であるため、可能です
パターンによるメッセージの投稿。 たとえば、キー「fanat」を使用してエクスチェンジ「php」に投稿すると、キュー「php.fanat」にメッセージが送信され、キー「fisher」を使用してエクスチェンジ「mysql」にメッセージを公開すると、キュー「mysql.fisher」にメッセージが送信されます(mysql chat ) これは、いわゆる直接タイプの交換です。 ただし、すべてのチャット参加者にメッセージを送信する必要があります。ここではパターンが使用されます。参加者の名前の代わりに「*」を指定すると、すべての署名済み(バインド関連)キューにメッセージが送信されます。 たとえば、fisher-fixxerなどのプライベートチャットを整理するには、直接キーを使用して公開できます。
// sendPrivateMessage.php
$rabbit = new Rabbit(); // connection
$msg = " , ...";
$rabbit->publish('php','fisher',$msg); //
最も興味深いのは、キーを変更するだけでなく、他に何もする必要がないということです。AMQPブローカーがすべてを行います。
技術的には、チャットWebページからurlにAJAX POSTリクエストを送信することで公開が行われます:sendMessage.phpプライバシーは追加のパラメーターで決定できます。
WEBクライアントがなかった場合、前述のように、別のアプローチがあります。
したがって、この場合、クラシックキューサブスクリプションは適していません。 キューの一定の非同期ポーリングを編成する必要があります。 一般に、チャットの原則は、サーバーに新しいメッセージがないかどうか常にポーリングし、メッセージがある場合はそれを表示することです。 ここでも、新しいものは何も発明されていません。 チャットのWebページから、キュークエリスクリプトのAJAXリクエストを作成します
define("MSGCOUNT", 5);
$rabbit = new Rabbit(); // connection
$countMessage = $rabbit->queue('php.fisher'); // -
$msg = array();
if (!$countMessage)
return json_encode( $msg ); //
for ($i=0;$i< MSGCOUNT) {
$res = $rabbit->getQueueItem('php');
if ($res['count'],0) break;
$msg[] = $res['msg'];
}
return json_encode( array( 'msg' => $msg ,
'count'=>$res['count'],
)); //
define("MSGCOUNT", 5);
$rabbit = new Rabbit(); // connection
$countMessage = $rabbit->queue('php.fisher'); // -
$msg = array();
if (!$countMessage)
return json_encode( $msg ); //
for ($i=0;$i< MSGCOUNT) {
$res = $rabbit->getQueueItem('php');
if ($res['count'],0) break;
$msg[] = $res['msg'];
}
return json_encode( array( 'msg' => $msg ,
'count'=>$res['count'],
)); //
このコードは、MSGCOUNTまたはそれらの数が少ない場合はすべてを読み取り、メッセージキュー(msgキー)から受信したメッセージとともにJSONを返し、残りのキーは 'count'です
いくつかの未解決の質問があります
たとえば、チャットに短いメッセージ履歴を残し、タンクにいる最後の5つにしたい...
AMQP_NOASKフラグを使用すると、メッセージに未読のマークが付けられます。 チャットに入ると、最後の15を除いて、すべてのメッセージを既読として読み取ります。 たとえば、リフレクション用のフィールドがまだあります-大量のメッセージをキューに保存する価値があるかどうか。 または、新しい着信メッセージ用に最後の5〜10個のメッセージの一時キューを編成します。 一般的に、実験の余地があります。