Topic Exchange

此模式下交换机,在推送消息时, 会根据消息的主题词和队列的主题词决定将消息推送到哪个队列. 交换机只会为 Queue 分发符合其指定的主题的消息。

  1. 向交换机发送消息时,消息的 routing key 就是主题关键词,主题词不能随意设置,必须由 "." 联结多个主题词 (如:log.error、log.warn) .
  2. 必须将队列显示的绑定到指定的交换机上.
  3. 为队列指定队列主题词时,可以使用通配符: "#": 表示 0 或多个主题词; "*": 表示 1 个主题词.

示例

producer.php

header('Content-Type: text/html; charset=utf-8');
// 连接设置
$conConfig = [
'host' => '127.0.0.1',
'port' => 5672,
'login' => 'root',
'password' => 'root',
'vhost' => '/'
]; try
{
// RabbitMQ 连接实例
$con = new AMQPConnection($conConfig);
// 发起连接
$con->connect();
// 判断连接结果,true成功,false失败
if(!$con->isConnected())
{
echo '连接失败';die;
}
// 新建通道
$channel = new AMQPChannel($con);
// 在指定通道上新建交换机,如果新建的交换机与已存在交换机重名但属性不同,会产生406错误。如果新建交换机与已存在交换机完全相同,不会有任何影响
$exchange = new AMQPExchange($channel);
// 交换机名称
$exchange->setName('test.topic');
// 交换机类型:按主题分发消息
$exchange->setType('topic');
// 声明交换机
$exchange->declareExchange(); // 发送消息到交换机,通过routing key指定消息的主题词
$state = $exchange->publish('apple', 'fruit.red');
if($state) echo 'Success' . PHP_EOL;
else echo 'Fail' . PHP_EOL; $state = $exchange->publish('cat', 'animal.red');
if($state) echo 'Success' . PHP_EOL;
else echo 'Fail' . PHP_EOL; $con->disconnect();
}
catch(Exception $e)
{
echo $e->getMessage();
}

consumer.php

header('Content-Type: text/html; charset=utf-8');
// 连接设置
$conConfig = [
'host' => '127.0.0.1',
'port' => 5672,
'login' => 'root',
'password' => 'root',
'vhost' => '/'
]; try
{
$connect = new AMQPConnection($conConfig);
$connect->connect();
if(!$connect->isConnected())
{
echo '连接失败';die;
} $channel = new AMQPChannel($connect);
$exchange = new AMQPExchange($channel);
$exchange->setName('test.topic');
$exchange->setType('topic');
$exchange->declareExchange(); // 创建两个队列, 一个关联red主题词, 一个关联animal主题词
$queueRed = new AMQPQueue($channel);
$queueAnimal = new AMQPQueue($channel);
// 队列名称
$queueRed->setName('red.queue');
$queueAnimal->setName('animal.queue');
// 声明队列
$queueRed->declareQueue();
$queueAnimal->declareQueue();
// 为队列绑定主题词, *: 匹配0或多个任意主题词, #: 1个任意主题词. 绑定主题词时, 主题词出现的位置也要匹配
$queueRed->bind('test.topic', "*.red");
$queueAnimal->bind('test.topic', 'animal.#'); echo 'red queue: ' . PHP_EOL;
while($msgEnvelope = $queueRed->get(AMQP_AUTOACK))
{
$msg = $msgEnvelope->getBody();
echo $msg . PHP_EOL;
} echo 'animal queue: ' . PHP_EOL;
while($msgEnvelope = $queueAnimal->get(AMQP_AUTOACK))
{
$msg = $msgEnvelope->getBody();
echo $msg . PHP_EOL;
} $connect->disconnect();
}catch(Exception $e)
{
echo $e->getMessage();
}

运行结果:

red queue 获得了所有包含 red 主题词的消息, animal queue 仅获得包含 animal 主题的消息.

Fanout Exchange

该模式下的交换机是广播模式, 交换机会向所有绑定的队列分发消息, 不需要设置交换机和队列的 routing key. 即使设置了, 也会被忽略.

示例

producer.php

 header('Content-Type: text/html; charset=utf-8');
// 连接设置
$conConfig = [
'host' => '127.0.0.1',
'port' => 5672,
'login' => 'root',
'password' => 'root',
'vhost' => '/'
]; try
{
// RabbitMQ 连接实例
$con = new AMQPConnection($conConfig);
// 发起连接
$con->connect();
// 判断连接结果,true成功,false失败
if(!$con->isConnected())
{
echo '连接失败';die;
}
// 新建通道
$channel = new AMQPChannel($con);
// 在指定通道上新建交换机,如果新建的交换机与已存在交换机重名但属性不同,会产生406错误。如果新建交换机与已存在交换机完全相同,不会有任何影响
$exchange = new AMQPExchange($channel);
// 交换机名称
$exchange->setName('test.fanout');
// 交换机类型:广播模式
$exchange->setType('fanout');
// 声明交换机
$exchange->declareExchange(); for($i = 0; $i < 3; $i++)
{
$msg = '消息';
// 发送消息到交换机,Fanout模式下不需要指定routing key。即使指定也会被忽略
$state = $exchange->publish($msg . $i);
if($state)
{
echo 'Success' . PHP_EOL;
}else
{
echo 'Fail' . PHP_EOL;
}
} $con->disconnect();
}
catch(Exception $e)
{
echo $e->getMessage();
}

consumer.php

 header('Content-Type: text/html; charset=utf-8');
// 连接设置
$conConfig = [
'host' => '127.0.0.1',
'port' => 5672,
'login' => 'root',
'password' => 'root',
'vhost' => '/'
]; try
{
$connect = new AMQPConnection($conConfig);
$connect->connect();
if(!$connect->isConnected())
{
echo '连接失败';die;
} $channel = new AMQPChannel($connect); $exchange = new AMQPExchange($channel);
$exchange->setName('test.fanout');
$exchange->setType('fanout');
$exchange->declareExchange(); // 创建队列
$queue1 = new AMQPQueue($channel);
$queue2 = new AMQPQueue($channel); // 队列名称
$queue1->setName('queue1');
$queue2->setName('queue2');
// 声明队列
$queue1->declareQueue();
$queue2->declareQueue();
// 绑定队列到交换机。Fanout模式下不需要指定routing key,即使指定也会被忽略
$queue1->bind('test.fanout');
echo '队列1: ' . PHP_EOL;
while($msgEnvelope = $queue1->get(AMQP_AUTOACK))
{
$msg = $msgEnvelope->getBody();
echo $msg . PHP_EOL;
} echo PHP_EOL . '队列2: ' . PHP_EOL;
$queue2->bind('test.fanout');
while($msgEnvelope = $queue2->get(AMQP_AUTOACK))
{
$msg = $msgEnvelope->getBody();
echo $msg . PHP_EOL;
}
$connect->disconnect();
}catch(Exception $e)
{
echo $e->getMessage();
}

运行结果:

两个队列获得相同的消息.

PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (二) -- Topic Exchange 和 Fanout Exchange的更多相关文章

  1. PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (一) -- 安装 AMQP 扩展和 Direct Exchange 模式

    Windows 安装 amqp 扩展 RabbitMQ 是基于 amqp(高级消息队列协议) 协议的.使用 RabbitMQ 前必须为 PHP 安装相应的 amqp 扩展. 下载相应版本的 amqp ...

  2. PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (三) -- Header Exchange

    此模式下,消息的routing key 和队列的 routing key 会被完全忽略,而是在交换机推送消息和队列绑定交换机时, 分别为消息和队列设置 headers 属性, 通过匹配消息和队列的 h ...

  3. PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (五) -- 自动 ACK、手动 ACK、NACK

    以 Direct 类型的 交换机和 Queue 的 get 方法为例. producer.php // 连接设置 $conConfig = [ 'host' => '127.0.0.1', 'p ...

  4. PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (四) -- Push API 和 Pull API

    RabbitMQ 中针对消息的分发提供了 Push API (订阅模式) 和 Pull API (主动获取) 两种模式. 在 PHP 中, 这两种模式分别通过 AMQPQueue 类中的 consum ...

  5. Windows下基于python3使用word2vec训练中文维基百科语料(二)

    在上一篇对中文维基百科语料处理将其转换成.txt的文本文档的基础上,我们要将为文本转换成向量,首先都要对文本进行预处理 步骤四:由于得到的中文维基百科中有许多繁体字,所以我们现在就是将繁体字转换成简体 ...

  6. flask框架----基于flask的扩展实现的简单的页面登录

    废话不多说,直接上代码 from flask import Flask,render_template,request,redirect,session app = Flask(__name__,te ...

  7. gtk+3.0的环境配置及基于gtk+3.0的python简单样例

    /*********************************************************************  * Author  : Samson  * Date   ...

  8. memcached学习——常用命令+基于java客户端的3种简单实现(二)

    常用命令: memcached设计的原则就是简单,所以支持的命令也不是特别多~ 1.查看memcached的状态,主要用于分析内存的使用状况.优化内存分配等 stats 查看memcached的运行状 ...

  9. php的amqp扩展 安装(windows) rabbitmq学习篇

    因为RabbitMQ是由erlang语言实现的,所以先要安装erlang环境erlang 下载安装 http://www.erlang.org/download.htmlrabbitmq 下载安装 h ...

随机推荐

  1. 【TJOI 2014】 上升子序列

    [题目链接] 点击打开链接 [算法] 先考虑50分的做法 : f[i]表示以i结尾的本质不同的上升子序列的个数 则f[i] = sigma(f[j]) (j < i,a[j] < a[i] ...

  2. 【SCOI 2005】 繁忙的都市

    [题目链接] 点击打开链接 [算法] 题目描述比较繁琐,但细心观察后,发现其实就是用kruskal算法求最小生成树 [代码] #include<bits/stdc++.h> using n ...

  3. Linux网络协议栈(三)——网络设备(1)

    网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1)    作为基于硬件的网络适配器与基于软件的协 ...

  4. oauth X-Frame-Options 跳转授权页面时,302重定向禁用iframe

    因为oauth/authorize响应头包含X-Frame-Options: DENY解决方案:openresty nginx 移除该属性,经测试生效 more_clear_headers X-Fra ...

  5. mysql case 列名 when 和 case when的区别

    最近写了一个sql,才发现有些情况不能用case 列名 when ( and then and and 7.9 then '中' else '差' END ) score_type, 我发现这样写查出 ...

  6. Luogu P2921 在农场万圣节 【tarjan in 有向图】 By cellur925

    题目传送门 上来就想到既直接又简单的暴力方法,顺着每个房间的下一个走下去就好了,但是没想到最坏情况会达到1e5,100000的数据铁定超时. #include<cstdio> #inclu ...

  7. 依赖注入(二)Autofac简单使用

    Autofac简单使用 源码下载传上源码,终于学会传文件了. 首先 还是那句话:“不要信我,否则你死得很惨!”. C#常见的依赖注入容器 IoC in .NET part 1: Autofac IoC ...

  8. concurrent包下的Exchanger练习

    Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据. 当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exc ...

  9. pytest特色与实用插件

    pytest特色 1.fixture的特点 fixture是pytest特有的功能,其特点如下: 必须用pytest.fixture装饰器装饰:fixture有明确的名字,在其他函数(function ...

  10. 前端_vue-cli+element-ui+AceEditor+codemirror+electron-vue

    因项目工作需要,目前在研究前端的一些知识.主要想实现一个类似于webstorm,可以实现对本地文件进行增删改查等操作的IDE.下面通过几个专题,循序渐进,对某一些部分进行总结,希望能对你有帮助.(网上 ...