Tp6使用RabbitMQ消息队列

1、安装thinkphp6框架
composer create-project topthink/think tp 

2、安装workerman扩展

cd tp
composer require topthink/think-worker
//或者下面的命令
composer require topthink/think-worker=3.0.7 -vvv

3、安装rabbitmq扩展

composer require workerman/rabbitmq

代码编写

生产者
  • 在app目录下新建workerman目录,并在其下创建Send.php文件,$options数组中的host地址改成你的rabbitmq地址。
  • <?php
     
    namespace app\workerman;
    use Bunny\Channel;
    use Workerman\RabbitMQ\Client;
    use think\worker\Server;
    class Send extends Server
    {
        //websocket地址,一会用于测试。
        protected $socket = 'websocket://127.0.0.1:2345';
     
        /**
         * 收到信息
         * @param $connection
         * @param $data
         */
        public function onMessage($connection, $data)
        {
            //websocket发送过来的消息
            $connection->send('我收到你的信息了:'.$data);
            //rabbitMQ配置
            $options = [
                'host'=>'127.0.0.1',//rabbitMQ IP
                'port'=>5672,//rabbitMQ 通讯端口
                'user'=>'admin',//rabbitMQ 账号
                'password'=>'123456'//rabbitMQ 密码
            ];
            (new Client($options))->connect()->then(function (Client $client) {
                return $client->channel();
            })->then(function (Channel $channel) {
                /**
                 * 创建队列(Queue)
                 * name: ceshi         // 队列名称
                 * passive: false      // 如果设置true存在则返回OK,否则就报错。设置false存在返回OK,不存在则自动创建
                 * durable: true       // 是否持久化,设置false是存放到内存中RabbitMQ重启后会丢失,
                 *                        设置true则代表是一个持久的队列,服务重启之后也会存在,因为服务会把持久化的Queue存放在硬盘上,当服务重启的时候,会重新加载之前被持久化的Queue
                 * exclusive: false    // 是否排他,指定该选项为true则队列只对当前连接有效,连接断开后自动删除
                 *  auto_delete: false // 是否自动删除,当最后一个消费者断开连接之后队列是否自动被删除
                 */
                return $channel->queueDeclare('ceshi', false, true, false, false)->then(function () use ($channel) {
                    return $channel;
                });
            })->then(function (Channel $channel) use($data){
                echo "发送消息内容:".$data."\n";
     
                /**
                 * 发送消息
                 * body 发送的数据
                 * headers 数据头,建议 ['content_type' => 'text/plain'],这样消费端是springboot注解接收直接是字符串类型
                 * exchange 交换器名称
                 * routingKey 路由key
                 * mandatory
                 * immediate
                 * @return bool|PromiseInterface|int
                 */
     
                return $channel->publish($data, ['content_type' => 'text/plain'], '', 'ceshi')->then(function () use ($channel) {
                    return $channel;
                });
            })->then(function (Channel $channel) {
                //echo " [x] Sent 'Hello World!'\n";
                $client = $channel->getClient();
                return $channel->close()->then(function () use ($client) {
                    return $client;
                });
            })->then(function (Client $client) {
                $client->disconnect();
            });
        }
     
        /**
         * 当连接建立时触发的回调函数
         * @param $connection
         */
        public function onConnect($connection)
        {
     
        }
     
        /**
         * 当连接断开时触发的回调函数
         * @param $connection
         */
        public function onClose($connection)
        {
     
        }
        /**
         * 当客户端的连接上发生错误时触发
         * @param $connection
         * @param $code
         * @param $msg
         */
        public function onError($connection, $code, $msg)
        {
            echo "error $code $msg\n";
        }
     
        /**
         * 每个进程启动
         * @param $worker
         */
        public function onWorkerStart($worker)
        {
     
     
        }
    }
    

  • 在config/worker_server.php中设置worker_class值为'app\workerman\Send'

  • 启动这个生产者

  • php think worker:server
    
    方式1:通过tcp发送数据
  • 发送数据
    通过在线网址发送数据(websocket方式),->传送门<-
    输入【ws://127.0.0.1:2345】后点击发送数据!
  • 前往rabbitMQ控制台查看

    至此,生产这一步就走完了,那么如果我不想通过websocket方式,想用tcp方式生产数据怎么办?
  • 方式2:通过tcp发送数据

    接口给内置服务器发消息->内置服务去发消息给rabbitMQ

  • 将Send.php中websocket:127.0.0.1改成tcp:127.0.0.1
  • 重启服务
  • 把controller目录中Index.php修改为以下内容
    <?php
    namespace app\controller;
    use think\Request;
    use app\BaseController;
     
    class Index extends BaseController
    {
        public function index(Request $request)
        {
        	$data = $this->request->param();
        	// var_dump($data);
        	//数组序列化
        	$shuju = serialize($data);
        	// var_dump($shuju);
        	//数组反序列化
        	$shuju2 = unserialize($shuju);
        	// var_dump($shuju2);die;
            //连接本地tcp服务
            $client = stream_socket_client('tcp://127.0.0.1:2345', $errno, $errmsg, 1);
            //发送字符串
            fwrite($client, $shuju."\n");
            //断开服务
            fclose($client);
            return '存入数据成功';
        }
     
    }
    

    用Postman、apifox等等访问对应接口就好,也会有数据进入队列
    消费者
    同生产者一样新创建一个thinkphp6项目,注意端口别和生产者冲突!这里我设置的是2346端口

    在app目录下新建workerman目录,并在其下创建Receive.php文件,$options数组中的host地址改成你的rabbitmq地址。

  • <?php
     
    namespace app\workerman;
    use Bunny\Channel;
    use Bunny\Message;
    use Workerman\RabbitMQ\Client;
    use think\worker\Server;
    class Receive extends Server
    {
        protected $socket = 'tcp://127.0.0.1:2346';
     
        /**
         * 收到信息
         * @param $connection
         * @param $data
         */
        public function onMessage($connection, $data)
        {
     
        }
     
        /**
         * 当连接建立时触发的回调函数
         * @param $connection
         */
        public function onConnect($connection)
        {
     
        }
     
        /**
         * 当连接断开时触发的回调函数
         * @param $connection
         */
        public function onClose($connection)
        {
     
        }
        /**
         * 当客户端的连接上发生错误时触发
         * @param $connection
         * @param $code
         * @param $msg
         */
        public function onError($connection, $code, $msg)
        {
            echo "error $code $msg\n";
        }
     
        /**
         * 每个进程启动
         * @param $worker
         */
        public function onWorkerStart($worker)
        {
            //rabbitMQ配置
            $options = [
                'host'=>'127.0.0.1',//rabbitMQ IP
                'port'=>5672,//rabbitMQ 通讯端口
                'user'=>'admin',//rabbitMQ 账号
                'password'=>'123456'//rabbitMQ 密码
            ];
            (new Client($options))->connect()->then(function (Client $client) {
                return $client->channel();
            })->then(function (Channel $channel) {
                /**
                 * 创建队列(Queue)
                 * name: ceshi         // 队列名称
                 * passive: false      // 如果设置true存在则返回OK,否则就报错。设置false存在返回OK,不存在则自动创建
                 * durable: true       // 是否持久化,设置false是存放到内存中RabbitMQ重启后会丢失,
                 *                        设置true则代表是一个持久的队列,服务重启之后也会存在,因为服务会把持久化的Queue存放在硬盘上,当服务重启的时候,会重新加载之前被持久化的Queue
                 * exclusive: false    // 是否排他,指定该选项为true则队列只对当前连接有效,连接断开后自动删除
                 *  auto_delete: false // 是否自动删除,当最后一个消费者断开连接之后队列是否自动被删除
                 */
                return $channel->queueDeclare('ceshi', false, true, false, false)->then(function () use ($channel) {
                    return $channel;
                });
            })->then(function (Channel $channel) {
                echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";
                $channel->consume(
                    function (Message $message, Channel $channel, Client $client) {
                        echo "接收消息内容:", $message->content, "\n";
                    },
                    'ceshi',
                    '',
                    false,
                    true
                );
            });
     
        }
    }
    

  • 在config/worker_server.php中设置worker_class值为'app\workerman\Receive',并将端口改为2346

  • 启动这个消费者

  • php think worker:server
    

    到这里消费者也就结束啦!

    使用

    接下来我用cmd来启动两个服务,然后用接口发送消息和消费测试!

  • 借鉴:Thinkphp6使用RabbitMQ消息队列_thinkphp6 rabbitmq-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xingxingwuxin

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值