[RabbitMQ] 测试生产者和消费者

268 阅读1分钟
如果是windows中使用
  • 1.config/rabbitmq.php中的host修改
  • 2.安装扩展composer require php-amqplib/php-amqplib, 因为是远程连接, 所以本地不用安装

  • 1.创建生产者和消费者的测试命令
 php think make:command Sender sender
 php think make:command Receiver receiver
  • 2.加入到自定义指令中
return [
    // 指令定义
    'commands' => [
         'hello' => 'app\command\Hello',    
         'receiver' => 'app\command\Receiver',    
         'sender' => 'app\command\Sender',    
    ],
];
  • 3.生产者代码 app\command\Sender.php
<?php
declare (strict_types = 1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use app\common\service\RabbitMQService;

class Sender extends Command
{
    
    public $queueA = 'queueA';
    public $queueB = 'queueB'; 
        
    protected function configure()
    {
        // 指令配置
        $this->setName('sender')
            ->setDescription('the sender command');
    }

    protected function execute(Input $input, Output $output)
    {
        // 指令输出
        $output->writeln('发送者工作中');
        $num = mt_rand(1, 10);
        if ($num > 5) {
             $output->writeln('发送队列B');
            $this->sendB();
        } else {
            $output->writeln('发送队列A');
            $this->sendA();
        }
    }
    
    protected function sendA()
    {
        
        $rabbitMQService = new RabbitMQService();
        // 发送消息
        $rabbitMQService->sendMessage("Hello, 我是发送者A! 这条信息发送到队列A", $this->queueA);
    }
    
    protected function sendB()
    {
       
        $rabbitMQService = new RabbitMQService();
        // 发送消息
        $rabbitMQService->sendMessage("Hello, 我是发送者B! 这条信息发送到队列B", $this->queueB);
    }
}
  • 4.消费者代码 app\command\Receiver.php
<?php
declare (strict_types = 1);

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use app\common\service\RabbitMQService;

class Receiver extends Command
{
    public $queueA = 'queueA';
    public $queueB = 'queueB'; 
    
    protected function configure()
    {
        // 指令配置
        $this->setName('receiver')
            ->setDescription('the receiver command');
    }

    protected function execute(Input $input, Output $output)
    {
        // 指令输出
        $output->writeln(' 接收者工作中...');
        
        $rabbitMQService = new RabbitMQService();
        
      // 接收消息
       $callback = function ($msg) {
           echo  "我是接收者, 接收到消息: " . $msg->body . "\n";
       };
       $rabbitMQService->receiveMessage($callback, $this->queueA); //方法是阻塞的, 所以不能同时接收两个队列的消息,如果需要, 多创建一个接收进程
       // $rabbitMQService->receiveMessage($callback, $this->queueB);
    }
}
  • 服务类代码 app\common\service\RabbitMQService.php
<?php

namespace app\common\service;

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use think\facade\Config;

class RabbitMQService
{
    private $connection;
    private $channel;

    public function __construct()
    {
        $config = Config::get('rabbitmq.default');
        $this->connection = new AMQPStreamConnection(
            $config['host'],
            $config['port'],
            $config['user'],
            $config['password'],
            $config['vhost']
        );
        $this->channel = $this->connection->channel();
    }

    public function __destruct()
    {
        $this->channel->close();
        $this->connection->close();
    }

    public function sendMessage($message, $queue = 'hello')
    {
        $config = Config::get('rabbitmq.queues.' . $queue);

        $this->channel->queue_declare(
            $config['queue'],
            false,
            false,
            false,
            false
        );

        $msg = new AMQPMessage($message);
        $this->channel->basic_publish($msg, $config['exchange'], $config['routing_key']);

        return true;
    }

    public function receiveMessage($callback, $queue = 'hello')
    {
        $config = Config::get('rabbitmq.queues.' . $queue);

        $this->channel->queue_declare(
            $config['queue'],
            false,
            false,
            false,
            false
        );

        $this->channel->basic_consume(
            $config['queue'],
            '',
            false,
            true,
            false,
            false,
            $callback
        );

        while ($this->channel->is_consuming()) {
            $this->channel->wait();
        }
    }
}
  • rabbitMQ配置
return [
    'default' => [
        'host' => 'localhost',
        'port' => 5672,
        'user' => 'admin',
        'password' => '',
        'vhost' => '/',
    ],
    'queues' => [
        'hello' => [
            'exchange' => '', // 交换机名称,不填表示使用默认的
            'queue' => 'hello', //队列名
            'routing_key' => 'hello', // 路由键,一般和队列名相同
        ],
        'queueA' => [
            'exchange' => '',
            'queue' => 'queueA',
            'routing_key' => 'queueA',
        ],
        'queueB' => [
            'exchange' => '',
            'queue' => 'queueB',
            'routing_key' => 'queueB',
        ],
    ],
];