[译]RabbitMQ教程一(PHP版)--HELLO WORLD

  • 作者:卡牌
  • 时间:2019-03-04
  • 阅读量:120

官方英文文档

介绍

RabbitMQ是一个消息代理:它接收并且转发信息。你可以把它当作一个邮局:当你把邮件放到投递箱的时候,你可以确定邮递员最终会将邮件发送到收件人手中。RabbitMQ就扮演着邮箱、邮局、快递员的角色。

RabbitMQ和邮局的主要区别是RabbitMQ并不处理纸质邮件,而是接收、存储和发送二进制数据--消息。

RabbitMQ发送信息有如下术语:

生产者:发送信息的程序就是一个生产者

以下图片代表生产者

producer.png

队列:在RabbitMQ中,队列相当于邮箱。尽管消息在RabbitMQ和应用程序之间传递,但是他们只能被存储在队列里。一个队列只能在主机内存或磁盘中,它本质上是一个很大的消息缓冲区。多个生产者可以发送信息到一个队列中,并且多个消费者也能尝试从一个队列中接收信息。

以下图片代表队列 

queue.png

消费者:消费者有相同的意义,即接收数据。消费者是等到接收数据的程序。

以下图片代表消费者 

consumer.png

注意,生产者、消费者、以及RabbitMQ代理,不需要在同一主机上。实际上在大部分应用程序中他们不在同一主机。一个应用程序既可以是生产者也可以是消费者。

HELLO WORLD

(基于php-amqplib客户端)

在这部分教程中将在PHP中写两个程序,一个是发送信息的生产者,一个是接收信息并打印出信息的接收者。我们将浏览一些 php-amqplib的API接口细节,先从简单的事情开始做:发送hello world信息.

在下图中,"P"是生产者,"C"是消费者。中间的盒子就是一个队列--RabbitMQ为了让消费者接收到消息而保持的消息缓冲区。

以下图片代表hello world图 

python-one.png

php-amqplib客户端库

RabbitMQ支持多少协议。此教程包含了开源的通场用来发送信息的协议:AMQP 0-9-1。 RabbitMQ有许多不同语言的客户端。我们在此教程中使用php-amqplib,composer作为依赖管理。在你的项目中添加composer.json

{
    "require": {
        "php-amqplib/php-amqplib": ">=2.6.1"
    }
}

确保安装了composer并且可以使用,运行如下命令

composer.phar install
#composer install # 或者运行如下命令

现在,我们已经安装了php-amqplib库,我们可以写一些代码

发送

sending.png

我们调用我们的信息发送者send.php和我们的信息接收者receive.php。发送者会连接RabbitMQ并且发送简单的信息,然后退出

在send.php中,我们需要包含如下库,并用use 使用必要的类

然后创立一个服务器的连接

// 建立连接,如果是非本机,需要创立一个拥有管理员标签的用户
$connection = 
new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');

$channel = $connection->channel();

在上面的代码中,$connection是socket连接的抽象,为我们处理了通信协议模板协商以及认证等功能。这样,我们就连接到了本地机器上的一个消息代理。如果我们需要连接不同主机的消息代理,我们需要简单的修改域名或者ip即可。

接下来,我们创立了一个通道。大部分的API操作均在这边完成。

对于send.php来说,我们必须申明一个队列用于发送信息。

$channel->queue_declare('hello', false, false, false, false);

$msg = new AMQPMessage('Hello World!');
$channel->basic_publish($msg, '', 'hello');

echo " [x] Sent 'Hello World!'\n";

队列的申明是幂等的,它仅仅在不存在时才会创建,消息的内容是一个字节数组,所以可以随意编码。

最后还要必须将通道和连接关闭。

这里是完成代码

channel();

$channel->queue_declare('hello', false, false, false, false);

$msg = new AMQPMessage('hello world!');
$channel->basic_publish($msg, '', 'hello');

echo "[x] sent 'hello world!'\n";

$channel->close();
$connection->close();

执行

php send.php
# [x] sent 'hello world!'    

接收者

上面代码是我们的信息发布者。我们的信息接收者监听RabbitMQ,不同于发布者发送一条信息就退出。我们将保持对信息的监听运行并且将他们打印出来。

以下图片代表接收者监听队列 

receiving.png

在receive.php有和send.php差不多的include文件和use命名空间。

与发布者设置相同,我们需要打开一个连接和一个通道,并且申明我们将要消费的队列,注意名字要与发布者中申明的队列名一致。

channel();

$channel->queue_declare('hello', false, false, false, false);

echo "[*] Waiting for message,To exit press CTRL+C\N";

注意,我们也在这里神明了一个队列,因为我们将在生产者之前开启消费者,我们在接收消费消息前也想确认队列是否存在。

我们讲到告知服务器发送我们送队列中取出来的数据,我们将定义一个PHP回调类型,用于接收服务器发送的消息。记住,这个过程是异步的。

channel();

$channel->queue_declare('hello', false, false, false, false);

echo "[*] Waiting for message,To exit press CTRL+C\N";

$callback = function ($msg) {
    echo '[x] Received ' . $msg->body ."\n";
};

$channel->basic_consume('hello', '', false, true, false, false, $callback);

while (count($channel->callbacks)){
    $channel->wait();
}
$channel->close();
$connection->close();

当$channel拥有回调的时候,我们的代码会所锁住。无论何时从回调函数中接收数据都会传递接收到的数据。

运行代码

运行消费者

php receive.php

运行生产者

php send.php

消费者将会打印送RabbitMQ中接收到的数据,接收者会一致保持运行,等待信息,(用 CTRL+C退出),所以可以送一个端发送到另外一个终端。

列出队列信息

你或许希望看到RabbitMQ拥有什么队列并且在其中有多少消息,你可以运行一下命令:

sudo rabbitmqctl list_queues

文章评论

共有0条评论来说两句吧...

提交
Top