参考 github
https://github.com/php-amqplib/php-amqplib
参考博客
https://www.cnblogs.com/fish-minuet/p/9771096.html
/**
生产者
*/
public function test()
{
$conf = [
'host' => config('api.MQCONFIG.host'),
'port' => config('api.MQCONFIG.port'),
'user' => config('api.MQCONFIG.username'),
'pwd' => config('api.MQCONFIG.password'),
'vhost' => '/',
];
$exchangeName = 'kd_sms_send_ex'; //交换机名
$queueName = 'kd_sms_send_q'; //队列名称
$routingKey = 'sms_send'; //路由关键字(也可以省略)
$conn = new AMQPStreamConnection( //建立生产者与mq之间的连接
$conf['host'], $conf['port'], $conf['user'], $conf['pwd'], $conf['vhost']
);
$channel = $conn->channel(); //在已连接基础上建立生产者与mq之间的通道
$channel->exchange_declare($exchangeName, 'direct', false, true, false); //声明初始化交换机
$channel->queue_declare($queueName, false, true, false, false); //声明初始化一条队列
$channel->queue_bind($queueName, $exchangeName, $routingKey); //将队列与某个交换机进行绑定,并使用路由关键字
$msgBody = json_encode(["name" => "1iGoo", "age" => 2122, "wqwqeqwe" => 'mai11111']);
$msg = new AMQPMessage($msgBody, ['content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]); //生成消息
$r = $channel->basic_publish($msg, $exchangeName, $routingKey); //推送消息到某个交换机
$channel->close();
$conn->close();
$this->success($r);
}
/**
消费者
执行命令 php think AMQP_JG
*/
declare (strict_types=1);
namespace app\command;
use app\service\amqp\AMQPConsumerService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Exception;
class xxxxQueue extends Command
{
protected function configure()
{
// 指令配置
$this->setName('AMQP_JG')->setDescription('the AMQP_JG command');
}
protected function execute(Input $input, Output $output)
{
$output->writeln('消费队列开始');
// $data = [
// 'title' => '消息标题',
// 'content' => '消息内容',
// 'create_by' => '创建者id',
// 'jump_path' => '',// 跳转类型:0.无跳转 1外部url跳转 其它自定义
// 'groupid' => '',// 值为-1时政府发送
// 'params' => '',// 参数地址
// 'platform_id' => '',// 平台id
// 'enterprise_id' => '',// 企业id
// 'user_id' => '',// 用户id
// ];
$exchange = 'xxxx_exchange'; // 交换机名称
$queue = 'xxxx_queue'; // 队列名
$routingKey = 'xxxx_letter'; //路由关键字
AMQPConsumerService::newsConsumption($exchange, $queue, $routingKey, function ($message) {
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$data = json_decode($message->body, true);
$this->saveMessage($data);
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']); // 消费回调
});
// 指令输出
$output->writeln('消费队列结束');
}
/**
* @param $data
* @throws Exception
* 发送消息 极光
*/
public function saveMessage($data)
{
try {
// 需要执行的业务
// 提交事务
return true;
} catch (\Exception $e) {
// 回滚事务
echo '消息发送失败' . $e->getMessage();
return false;
}
}
}
namespace app\service\amqp;
use PhpAmqpLib\Connection\AMQPStreamConnection;
/**
* 基类消费
* Class AMQPConsumerService
* @package app\service\amqp
*/
class AMQPConsumerService
{
const DIRECT = 'direct';
const FANOUT = 'fanout';
const TOPIC = 'topic'; //通配符模式
const HEADERS = 'headers';
/**
* @param $exchange string 交换机
* @param $queue string 队列名
* @param $routingKey string 路由
* @param $callback string 回调函数名称
* @return bool
*/
public static function newsConsumption($exchange, $queue, $routingKey, $callback)
{
$consumerTag = '';//consumer
$conf = [
'host' => config('api.MQCONFIG.host'),
'port' => config('api.MQCONFIG.port'),
'user' => config('api.MQCONFIG.username'),
'pwd' => config('api.MQCONFIG.password'),
'vhost' => '/',
];
$connection = new AMQPStreamConnection($conf['host'], $conf['port'], $conf['user'], $conf['pwd'], $conf['vhost']);
$channel = $connection->channel();
/*
The following code is the same both in the consumer and the producer.
In this way we are sure we always have a queue to consume from and an
exchange where to publish messages.
*/
/*
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($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($exchange, self::DIRECT, false, true, false);
$channel->queue_bind($queue, $exchange, $routingKey);
/*
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:
callback: A PHP Callback
*/
$channel->basic_consume($queue, $consumerTag, false, false, false, false, $callback);
// $channel->basic_consume($queue, $consumerTag, false, false, false, false, 'process_message');
// register_shutdown_function('shutdown', $channel, $connection);
// Loop as long as the channel has callbacks registered
while (count($channel->callbacks)) {
$channel->wait();
}
$channel->close();
$connection->close();
return true;
}
}