$this->mq_host,
'port' => $this->mq_port1,
'user' => $this->mq_user,
'password' => $this->mq_passwd,
'vhost' => $this->mq_vhost
],
[
'host' => $this->mq_host,
'port' => $this->mq_port2,
'user' => $this->mq_user,
'password' => $this->mq_passwd,
'vhost' => $this->mq_vhost
],
[
'host' => $this->mq_host,
'port' => $this->mq_port3,
'user' => $this->mq_user,
'password' => $this->mq_passwd,
'vhost' => $this->mq_vhost
],
];
$options = [];
$this->connection = AMQPStreamConnection::create_connection($host,$options);
}
}
BasicConnect.php
connection->channel();
/**
* name: $queue 队列名称
* passive: false 不检查是否存在同名队列(don't check if a queue with the same name exists)
* durable: true 服务器重启后队列将无法生存(the queue will not survive server restarts)
* exclusive: false 可以通过其他通道访问队列(the queue can be accessed in other channels)
* auto_delete: false 一旦通道关闭,队列将不会被删除。(the queue won't be deleted once the channel is closed.)
*/
$channel->queue_declare($this->queue, false, true, false, false);
/**
* name: $exchange
* type: direct
* passive: false
* durable: true 服务器重启后交换机将仍存在(the exchange will survive server restarts)
* auto_delete: false 一旦频道关闭,将不会删除交换。(the exchange won't be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, true, false);
$channel->queue_bind($this->queue, $this->exchange);
# 仅发送1条数据
// $messageBody = 'it is a simple message';
// $message = new AMQPMessage($messageBody,['content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
// $channel->basic_publish($message, $this->exchange);
# 发送多条数据(注意,仅第一次创建AMQPMessage对象,其它通过setBody复用前面创建的对象)
$properties = ['content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT];
for($i=1;$i<10;$i++){
$messageBody = 'it is a simple message:'.$i;
if( $i == 1){
$message = new AMQPMessage($messageBody, $properties);
}else{
$message->setBody($messageBody);
}
$channel->basic_publish($message, $this->exchange);
}
$channel->close();
$this->connection->close();
exit;
}
}
SimpleProducer.php
connection->channel();
/**
* name: $queue 队列名称
* passive: false
* durable: true 服务器重启后队列将仍存在(the queue will survive server restarts)
* exclusive: false 可以通过其他通道访问队列(the queue can be accessed in other channels)
* auto_delete: false 一旦通道关闭,队列将不会被删除。(the queue won't be deleted once the channel is closed.)
*/
$channel->queue_declare($this->queue, false, true, false, false);
/**
* name: $exchange
* type: direct
* passive: false
* durable: true 服务器重启后交换机将仍存在(the exchange will survive server restarts)
* auto_delete: false 一旦频道关闭,将不会删除交换。(the exchange won't be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, true, false);
$channel->queue_bind($this->queue, $this->exchange);
/**
* queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
* consumer_tag: 消费者标识符(Consumer identifier)
* no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
* no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
* exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
* nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
* callback: 回调函数(A PHP Callback)
*/
$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);
register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);
// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
while ($channel->is_consuming()) {
$channel->wait();
}
exit;
}
/**
* 回调函数
*/
public function process_message($message){
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
if ($message->body === 'quit') {
$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
}
}
/**
* @param \PhpAmqpLib\Channel\AMQPChannel $channel
* @param \PhpAmqpLib\Connection\AbstractConnection $connection
*/
public function shutdown($channel, $connection)
{
$channel->close();
$connection->close();
}
}
SimpleConsumer.php
connection->channel();
/**
* name: $exchange 交换机名称
* type: fanout 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::FANOUT, false, false, true);
$messageBody = 'I am a fanout message';
$message = new AMQPMessage($messageBody, ['content_type' => 'text/plain']);
$res = $channel->basic_publish($message, $this->exchange);
$channel->close();
$this->connection->close();
exit;
}
}
FanoutProducer.php
connection->channel();
/**
* name: $queue 队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
* passive: false 不检查是否存在同名队列(don't check if a queue with the same name exists)
* durable: false 服务器重启后队列将无法生存(the queue will not survive server restarts)
* exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
* auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
*/
$channel->queue_declare($this->queue, false, false, false, true);
/**
* name: $exchange 交换机名称
* type: fanout 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::FANOUT, false, false, true);
$channel->queue_bind($this->queue, $this->exchange);
/*
* queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
* consumer_tag: 消费者标识符(Consumer identifier)
* no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
* no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
* exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
* nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
* callback: 回调函数(A PHP Callback)
*/
$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);
register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);
// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
while ($channel->is_consuming()) {
$channel->wait();
}
exit;
}
/**
* 回调函数
*/
public function process_message($message){
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
if ($message->body === 'quit') {
$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
}
}
/**
* @param \PhpAmqpLib\Channel\AMQPChannel $channel
* @param \PhpAmqpLib\Connection\AbstractConnection $connection
*/
public function shutdown($channel, $connection)
{
$channel->close();
$connection->close();
}
}
FanoutConsumer1.php
connection->channel();
/**
* name: $queue 队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
* passive: false 不检查是否存在同名队列(don't check if a queue with the same name exists)
* durable: false 服务器重启后队列将无法生存(the queue will not survive server restarts)
* exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
* auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
*/
$channel->queue_declare($this->queue, false, false, false, true);
/**
* name: $exchange 交换机名称
* type: fanout 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::FANOUT, false, false, true);
$channel->queue_bind($this->queue, $this->exchange);
/*
* queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
* consumer_tag: 消费者标识符(Consumer identifier)
* no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
* no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
* exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
* nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
* callback: 回调函数(A PHP Callback)
*/
$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);
register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);
// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
while ($channel->is_consuming()) {
$channel->wait();
}
exit;
}
/**
* 回调函数
*/
public function process_message($message){
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
if ($message->body === 'quit') {
$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
}
}
/**
* @param \PhpAmqpLib\Channel\AMQPChannel $channel
* @param \PhpAmqpLib\Connection\AbstractConnection $connection
*/
public function shutdown($channel, $connection)
{
$channel->close();
$connection->close();
}
}
FanoutConsumer2.php
connection->channel();
/**
* name: $exchange 交换机名称
* type: DIRECT 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, false, true);
$messageBody = 'I am a direct message';
$message = new AMQPMessage($messageBody, ['content_type' => 'text/plain']);
$channel->basic_publish($message, $this->exchange, 'direct_key1');
$channel->close();
$this->connection->close();
exit;
}
}
DirectProducer.php
https://www.jianshu.com/p/fdb195698a5a
https://my.oschina.net/u/3698467/blog/1825316
connection->channel();
/**
* name: $queue 队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
* passive: false 不检查是否存在同名队列(don't check if a queue with the same name exists)
* durable: false 服务器重启后队列将无法生存(the queue will not survive server restarts)
* exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
* auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
*/
$channel->queue_declare($this->queue, false, false, false, true);
/**
* name: $exchange 交换机名称
* type: DIRECT 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, false, true);
$channel->queue_bind($this->queue, $this->exchange, 'direct_key1');
/*
* queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
* consumer_tag: 消费者标识符(Consumer identifier)
* no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
* no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
* exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
* nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
* callback: 回调函数(A PHP Callback)
*/
$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);
register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);
// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
while ($channel->is_consuming()) {
$channel->wait();
}
exit;
}
/**
* 回调函数
*/
public function process_message($message){
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
if ($message->body === 'quit') {
$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
}
}
/**
* @param \PhpAmqpLib\Channel\AMQPChannel $channel
* @param \PhpAmqpLib\Connection\AbstractConnection $connection
*/
public function shutdown($channel, $connection)
{
$channel->close();
$connection->close();
}
}
DirectConsumer1.php
connection->channel();
/**
* name: $exchange 交换机名称
* type: TOPIC 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::TOPIC, false, false, true);
$messageBody = 'I am a TOPIC message';
$message = new AMQPMessage($messageBody, ['content_type' => 'text/plain']);
$res = $channel->basic_publish($message, $this->exchange, 'key.1.2');#routing_key设置为key.1.2,只有TopicConsumer2{'key.#'}消费者能收到
#$res = $channel->basic_publish($message, $this->exchange, 'key.1');#routing_key设置为key.1,TopicConsumer1{'key.*'}和TopicConsumer2{'key.#'}消费者都可以收到
$channel->close();
$this->connection->close();
exit;
}
}
TopicProducer.php
*(星号)可以代替一个任意标识符 ;#(井号)可以代替零个或多个标识符。
https://blog.csdn.net/a491857321/article/details/50616323 (JAVA实现)
connection->channel();
/**
* name: $queue 队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
* passive: false 不检查是否存在同名队列(don't check if a queue with the same name exists)
* durable: false 服务器重启后队列将无法生存(the queue will not survive server restarts)
* exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
* auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
*/
$channel->queue_declare($this->queue, false, false, false, true);
/**
* name: $exchange 交换机名称
* type: TOPIC 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::TOPIC, false, false, true);
$channel->queue_bind($this->queue, $this->exchange, 'key.*');
/*
* queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
* consumer_tag: 消费者标识符(Consumer identifier)
* no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
* no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
* exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
* nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
* callback: 回调函数(A PHP Callback)
*/
$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);
register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);
// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
while ($channel->is_consuming()) {
$channel->wait();
}
exit;
}
/**
* 回调函数
*/
public function process_message($message){
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
if ($message->body === 'quit') {
$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
}
}
/**
* @param \PhpAmqpLib\Channel\AMQPChannel $channel
* @param \PhpAmqpLib\Connection\AbstractConnection $connection
*/
public function shutdown($channel, $connection)
{
$channel->close();
$connection->close();
}
}
TopicConsumer1.php
connection->channel();
/**
* name: $queue 队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
* passive: false 不检查是否存在同名队列(don't check if a queue with the same name exists)
* durable: false 服务器重启后队列将无法生存(the queue will not survive server restarts)
* exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
* auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
*/
$channel->queue_declare($this->queue, false, false, false, true);
/**
* name: $exchange 交换机名称
* type: TOPIC 交换机类型
* passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
* durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
* auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
*/
$channel->exchange_declare($this->exchange, AMQPExchangeType::TOPIC, false, false, true);
$channel->queue_bind($this->queue, $this->exchange, 'key.#');
/*
* queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
* consumer_tag: 消费者标识符(Consumer identifier)
* no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
* no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
* exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
* nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
* callback: 回调函数(A PHP Callback)
*/
$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);
register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);
// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
while ($channel->is_consuming()) {
$channel->wait();
}
exit;
}
/**
* 回调函数
*/
public function process_message($message){
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
if ($message->body === 'quit') {
$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
}
}
/**
* @param \PhpAmqpLib\Channel\AMQPChannel $channel
* @param \PhpAmqpLib\Connection\AbstractConnection $connection
*/
public function shutdown($channel, $connection)
{
$channel->close();
$connection->close();
}
}
TopicConsumer2.php