From:http://lostechies.com/derekgreer/2012/05/16/rabbitmq-for-windows-fanout-exchanges/

PunCha: There is not too much to say about this topic....

RabbitMQ for Windows: Fanout Exchanges

Posted by Derek Greer on May 16, 2012

This is the sixth installment to the series: RabbitMQ for Windows. In the last installment, we walked through creating a direct exchange example and introduced the push API. In this installment, we’ll walk through a fanout exchange example.

As discussed earlier in the series, the fanout exchange type is useful for facilitating the publish-subscribe pattern. When we publish a message to a fanout exchange, the message is delivered indiscriminately to all bound queues. With the Direct, Topic, and Headers exchange types, a criteria is used by a routing algorithm taking the form of a routing key or a collection of message headers depending on the exchange type in question. A routing key or a collection of message headers may also be specified with the fanout exchange which will be delivered as part of the message’s metadata, but they will not be used as a filter in determining which queue receives a published message.

To demonstrate the fanout exchange, we’ll use a stock ticker example. In the previous example, logs were routed to queues based upon a matching routing key (an empty string in the logging example’s case). In this example, we’d like our messages to be delivered to all bound queues regardless of qualification.

Similar to the previous example, we’ll create a Producer console application which periodically publishes stock quote messages and a Consumer console application which displays the message to the console.

We’ll start our Producer app as before by establishing a connection using the default settings, creating the connection, and creating a channel:

namespace Producer
{
  class Program
  {
    static volatile bool _cancelling;     static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();
    }
  }
}

Next, we need to declare an exchange of type “fanout”. We’ll name our new exchange “fanout-exchange-example”:

channel.ExchangeDeclare("direct-exchange-example", ExchangeType.Fanout, false, true, null);

To publish the stock messages periodically, we’ll call a PublishQuotes() method with the provided channel and run it on a background thread:

var thread = new Thread(() => PublishQuotes(channel));
thread.Start();

Next, we’ll provide a way to exit the application by prompting the user to enter ‘x’ and use a simple Boolean to signal the background thread when to exit:

Console.WriteLine("Press 'x' to exit");
var input = (char) Console.Read();
_cancelling = true;

Lastly, we need to close the channel and connection:

channel.Close();
connection.Close();

For our PublishQuotes() method, well iterate over a set of stock symbols, retrieve the stock information for each symbol, and publish a simple string-based message in the form [symbol]:[price]:

static void PublishQuotes(IModel channel)
{
  while (true)
  {
    if (_cancelling) return;
    IEnumerable quotes = FetchStockQuotes(new[] {"GOOG", "HD", "MCD"});
    foreach (string quote in quotes)
    {
      byte[] message = Encoding.UTF8.GetBytes(quote);
      channel.BasicPublish("direct-exchange-example", "", null, message);
    }
    Thread.Sleep(5000);
  }
}

To implement the FetchStockQuotes() method, we’ll use the Yahoo Finance API which entails retrieving an XML-based list of stock quotes and parsing out the bit of information we’re interested in for our example:

static IEnumerable<string> FetchStockQuotes(string[] symbols)
{
  var quotes = new List<string>();   string url = string.Format("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20({0})&env=store://datatables.org/alltableswithkeys",
      String.Join("%2C", symbols.Select(s => "%22" + s + "%22")));
  var wc = new WebClient {Proxy = WebRequest.DefaultWebProxy};
  var ms = new MemoryStream(wc.DownloadData(url));
  var reader = new XmlTextReader(ms);
  XDocument doc = XDocument.Load(reader);
  XElement results = doc.Root.Element("results");   foreach (string symbol in symbols)
  {
    XElement q = results.Elements("quote").First(w => w.Attribute("symbol").Value == symbol);  
    quotes.Add(symbol + ":" + q.Element("AskRealtime").Value);
  }   return quotes;
}

Here is the complete Producer listing:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using RabbitMQ.Client; namespace Producer
{
  class Program
  {
    static volatile bool _cancelling;     static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();
      channel.ExchangeDeclare("direct-exchange-example", ExchangeType.Fanout, false, true, null);       var thread = new Thread(() => PublishQuotes(channel));
      thread.Start();       Console.WriteLine("Press 'x' to exit");
      var input = (char) Console.Read();
      _cancelling = true;       channel.Close();
      connection.Close();
    }     static void PublishQuotes(IModel channel)
    {
      while (true)
      {
        if (_cancelling) return;
        IEnumerable quotes = FetchStockQuotes(new[] {"GOOG", "HD", "MCD"});
        foreach (string quote in quotes)
        {
          byte[] message = Encoding.UTF8.GetBytes(quote);
          channel.BasicPublish("direct-exchange-example", "", null, message);
        }
        Thread.Sleep(5000);
      }
    }     static IEnumerable<string> FetchStockQuotes(string[] symbols)
    {
      var quotes = new List<string>();       string url = string.Format("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20({0})&env=store://datatables.org/alltableswithkeys",
          String.Join("%2C", symbols.Select(s => "%22" + s + "%22")));
      var wc = new WebClient {Proxy = WebRequest.DefaultWebProxy};
      var ms = new MemoryStream(wc.DownloadData(url));
      var reader = new XmlTextReader(ms);
      XDocument doc = XDocument.Load(reader);
      XElement results = doc.Root.Element("results");       foreach (string symbol in symbols)
      {
        XElement q = results.Elements("quote").First(w => w.Attribute("symbol").Value == symbol);  
        quotes.Add(symbol + ":" + q.Element("AskRealtime").Value);
      }       return quotes;
    }
  }
}

Our Consumer application will be similar to the one used in our logging example, but we’ll change the exchange name, queue name, and exchange type and put the processing of the messages within a while loop to continually display our any updates to our stock prices. Here’s the full listing for our Consumer app:

using System;
using System.IO;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events; namespace Consumer
{
  class Program
  {
    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();       channel.ExchangeDeclare("direct-exchange-example", ExchangeType.Fanout, false, true, null);
      channel.QueueDeclare("quotes", false, false, true, null);
      channel.QueueBind("quotes", "direct-exchange-example", "");       var consumer = new QueueingBasicConsumer(channel);
      channel.BasicConsume("quotes", true, consumer);       while (true)
      {
        try
        {
          var eventArgs = (BasicDeliverEventArgs) consumer.Queue.Dequeue();
          string message = Encoding.UTF8.GetString(eventArgs.Body);
          Console.WriteLine(message);
        }
        catch (EndOfStreamException)
        {
          // The consumer was cancelled, the model closed, or the connection went away.
          break;
        }
      }       channel.Close();
      connection.Close();
    }
  }
}

Setting our solution startup projects to run both the Producer and Consumer apps together, we should see messages similar to the following for the Consumer output:

GOOG:611.62
HD:48.66
MCD:91.06
GOOG:611.58
HD:48.66
MCD:91.06

To show our queue would receive messages published to the fanout exchange regardless of the routing key value, we can change the value of the routing key to “anything”:

channel.QueueBind("quotes", "direct-exchange-example", "anything");

Running the application again shows the same values:

GOOG:611.62
HD:48.66
MCD:91.06
GOOG:611.58
HD:48.66
MCD:91.06

That concludes our fanout exchange example. Next time, we’ll take a look at the topic exchange type.

http://blog.csdn.net/puncha/article/details/8450063

RabbitMQ学习之:(七)Fanout Exchange (转贴+我的评论)的更多相关文章

  1. rabbitmq学习(七) —— springboot下的可靠使用

    前面的学习都是基于原生的api,下面我们使用spingboot来整合rabbitmq springboot对rabbitmq提供了友好支持,极大的简化了开发流程 引入maven <depende ...

  2. rabbitMQ学习(七)反馈模式

    反馈模式 在消费端接收到消息后,会反馈给服务器信息. 连接代码: import java.io.IOException; import com.rabbitmq.client.Channel; imp ...

  3. rabbitMQ学习笔记(七) RPC 远程过程调用

    关于RPC的介绍请参考百度百科里的关于RPC的介绍:http://baike.baidu.com/view/32726.htm#sub32726 现在来看看Rabbitmq中RPC吧!RPC的工作示意 ...

  4. RabbitMQ学习总结 第六篇:Topic类型的exchange

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  5. RabbitMQ学习系列(四): 几种Exchange 模式

    上一篇,讲了RabbitMQ的具体用法,可以看看这篇文章:RabbitMQ学习系列(三): C# 如何使用 RabbitMQ.今天说些理论的东西,Exchange 的几种模式. AMQP协议中的核心思 ...

  6. (七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中

    原文:(七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中 前面第六章我们使用的是direct直连模式来进行消息投递和分发.本章将介绍如何使用fanout模式将消息推送到多 ...

  7. RabbitMQ学习之:(六)Direct Exchange (转贴+我的评论)

    From: http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/ RabbitMQ fo ...

  8. RabbitMQ学习笔记4-使用fanout交换器

    fanout交换器会把发送给它的所有消息发送给绑定在它上面的队列,起到广播一样的效果. 本里使用实际业务中常见的例子, 订单系统:创建订单,然后发送一个事件消息 积分系统:发送订单的积分奖励 短信平台 ...

  9. PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (二) -- Topic Exchange 和 Fanout Exchange

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

随机推荐

  1. SiteOmat

    卡巴斯基实验室高级安全研究员Ido Naor和以色列安全研究员Amihai Neiderman在卡巴斯位于墨西哥坎昆举行的安全分析师峰会期间,就加油站的安全问题展开了全面分析.他们的研究表明,攻击者可 ...

  2. Django:中间件与csrf

    一.中间件 什么是中间件 中间件有什么用 自定义中间件 中间件应用场景 二.csrf csrf token跨站请求伪造 一.中间件 什么是中间件 中间件顾名思义,是介于request与response ...

  3. Java将字符串格式时间转化成Date格式

    可以通过 new 一个 SimpleDateFormat 对象,通过对象调用parse方法实现 示例代码: String time = "2019-07-23"; SimpleDa ...

  4. P3157 [CQOI2011]动态逆序对 (CDQ解决三维偏序问题)

    P3157 [CQOI2011]动态逆序对 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任 ...

  5. Git 分支开发规范

    您必须知道的 Git 分支开发规范 Git 是目前最流行的源代码管理工具. 为规范开发,保持代码提交记录以及 git 分支结构清晰,方便后续维护,现规范 git 的相关操作. 分支管理 分支命名 ma ...

  6. 【概率dp】vijos 3747 随机图

    没有养成按状态逐步分析问题的思维 题目描述 在一张图内,两点$i,j$之间有$p$的概率的概率生成一条边.求该图不出现大小$\ge 4$连通块的概率. $n \le 100,答案在实数意义下$ 题目分 ...

  7. 18-SQLServer中给视图创建索引

    一.注意点 1.索引视图所引用的基表必须在同一个数据库中,不是用union all引用多个数据库的表: 2.创建索引视图时要加上with schemabinding: 3.创建索引视图时要指定表所属的 ...

  8. Git 命令行解决冲突

    git add filename   将本地工作区文件加入缓存区 git commit filename -m '提交文件注释' git status  查看当前工作区状态 git fetch ori ...

  9. 引爆炸弹——DFS&&联通块

    题目 链接 在一个$n \times m$方格地图上,某些方格上放置着炸弹.手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去. 现在为了引爆地 ...

  10. DNS服务基础

    DNS服务器的功能 – 正向解析:根据注册的域名查找其对应的IP地址 – 反向解析:根据IP地址查找对应的注册域名(不常用) NS(声明DNS记录) A(正向解析记录) CNAME(解析记录别名) 安 ...