<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Aspiring Craftsman</title>
	
	<link>http://lostechies.com/derekgreer</link>
	<description>pursuing well-crafted software</description>
	<lastBuildDate>Tue, 14 May 2013 13:08:01 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/lostechies/aspiringcraftsman" /><feedburner:info uri="lostechies/aspiringcraftsman" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>RabbitMQ for Windows: Headers Exchanges</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/4pnFJtQMDhc/</link>
		<comments>http://lostechies.com/derekgreer/2012/05/29/rabbitmq-for-windows-headers-exchanges/#comments</comments>
		<pubDate>Tue, 29 May 2012 19:46:34 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=789</guid>
		<description><![CDATA[This is the eighth and final installment to the series: RabbitMQ for Windows.&#160; In the last installment, we walked through creating a topic exchange example.&#160; As the last installment, we’ll walk through a headers exchange example. Headers exchanges examine the&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/05/29/rabbitmq-for-windows-headers-exchanges/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the eighth and final installment to the series: RabbitMQ for Windows.&nbsp; In the <a href="http://lostechies.com/derekgreer/2012/05/18/rabbitmq-for-windows-topic-exchanges/">last installment</a>, we walked through creating a topic exchange example.&nbsp; As the last installment, we’ll walk through a headers exchange example.</p>
<p>Headers exchanges examine the message headers to determine which queues a message should be routed to.&nbsp; As discussed earlier in this series, headers exchanges are similar to topic exchanges in that they allow you to specify multiple criteria, but offer a bit more flexibility in that the headers can be constructed using a wider range of data types (<a href="#Footnote_1">1</a>).</p>
<p>To subscribe to receive messages from a headers exchange, a dictionary of headers is specified as part of the binding arguments.&nbsp; In addition to the headers, a key of “x-match” is also included in the dictionary with a value of “all”, specifying that messages must be published with all the specified headers in order to match, or “any”, specifying that the message needs to only have one of the specified headers specified.</p>
<p>As our final example, we’ll create a Producer application which publishes the message “Hello, World!” using a headers exchange.&nbsp; Here’s our Producer code:</p>
<pre class="prettyprint">using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using RabbitMQ.Client;
using RabbitMQ.Client.Framing.v0_9_1;

namespace Producer
{
  class Program
  {
    const string ExchangeName = "header-exchange-example";

    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      connectionFactory.HostName = "localhost";

      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();
      channel.ExchangeDeclare(ExchangeName, ExchangeType.Headers, false, true, null);
      byte[] message = Encoding.UTF8.GetBytes("Hello, World!");

      var properties = new BasicProperties();
      properties.Headers = new Dictionary&lt;string, object&gt;();
      properties.Headers.Add("key1", "12345");
      
      TimeSpan time = TimeSpan.FromSeconds(10);
      var stopwatch = new Stopwatch();
      Console.WriteLine("Running for {0} seconds", time.ToString("ss"));
      stopwatch.Start();
      var messageCount = 0;

      while (stopwatch.Elapsed &lt; time)
      {
        channel.BasicPublish(ExchangeName, "", properties, message);
        messageCount++;
        Console.Write("Time to complete: {0} seconds - Messages published: {1}\r", (time - stopwatch.Elapsed).ToString("ss"), messageCount);
        Thread.Sleep(1000);
      }

      Console.Write(new string(' ', 70) + "\r");
      Console.WriteLine("Press any key to exit");
      Console.ReadKey();
      message = Encoding.UTF8.GetBytes("quit");
      channel.BasicPublish(ExchangeName, "", properties, message);
      connection.Close();
    }
  }
}</pre>
<p>In the Producer, we’ve used a generic dictionary of type Dictionary&lt;string, object&gt; and added a single key “key1” with a value of “12345”.&nbsp; As with our previous example, we’re using a stopwatch as a way to publish messages continually for 10 seconds.</p>
<p>For our Consumer application, we can use an “x-match” argument of “all” with the single key/value pair specified by the Producer, or we can use an “x-match” argument of “any” which includes the key/value pair specified by the Producer along with other potential matches.&nbsp; We’ll use the latter for our example.&nbsp;&nbsp; Here’s our Consumer code:</p>
<pre class="prettyprint">using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace Consumer
{
  class Program
  {
    const string QueueName = "header-exchange-example";
    const string ExchangeName = "header-exchange-example";

    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      connectionFactory.HostName = "localhost";

      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();
      channel.ExchangeDeclare(ExchangeName, ExchangeType.Headers, false, true, null);
      channel.QueueDeclare(QueueName, false, false, true, null);

      IDictionary specs = new Dictionary<string object ,>();
      specs.Add("x-match", "any");
      specs.Add("key1", "12345");
      specs.Add("key2", "123455");
      channel.QueueBind(QueueName, ExchangeName, string.Empty, specs);

      channel.StartConsume(QueueName, MessageHandler);
      connection.Close();
    }

    public static void MessageHandler(IModel channel, DefaultBasicConsumer consumer, BasicDeliverEventArgs eventArgs)
    {
      string message = Encoding.UTF8.GetString(eventArgs.Body);
      Console.WriteLine("Message received: " + message);
      foreach (object headerKey in eventArgs.BasicProperties.Headers.Keys)
      {
        Console.WriteLine(headerKey + ": " + eventArgs.BasicProperties.Headers[headerKey]);
      }

      if (message == "quit")
        channel.BasicCancel(consumer.ConsumerTag);
    }
  }
}</pre>
<p>Rather than handling our messages inline as we’ve done in previous examples, this example uses an extension method named StartConsume() which accepts a callback to be invoked each time a message is received.&nbsp; Here’s the extension method used by our example:</p>
<pre class="prettyprint">using System;
using System.IO;
using System.Threading;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace Consumer
{
  public static class ChannelExtensions
  {
    public static void StartConsume(this IModel channel, string queueName,  Action&lt;IModel, DefaultBasicConsumer, BasicDeliverEventArgs&gt; callback)
    {
      var consumer = new QueueingBasicConsumer(channel);
      channel.BasicConsume(queueName, true, consumer);

      while (true)
      {
        try
        {
          var eventArgs = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
          new Thread(() =&gt; callback(channel, consumer, eventArgs)).Start();
        }
        catch (EndOfStreamException)
        {
          // The consumer was cancelled, the model closed, or the connection went away.
          break;
        }
      }
    }
  }
}</pre>
<p>Setting our solution to run both the Producer and Consumer applications upon startup, running our example produces output similar to the following:</p>
<p><strong>Producer</strong></p>
<pre class="prettyprint">Running for 10 seconds
Time to complete: 08 seconds - Messages published: 2</pre>
<p><strong>Consumer</strong></p>
<pre class="prettyprint">Message received: Hello, World!
key1: 12345
Message received: Hello, World!
key1: 12345</pre>
<p>That concludes our headers exchange example as well as the RabbitMQ for Windows series.&nbsp; For more information on working with RabbitMQ, see the documentation at <a href="http://www.rabbitmq.com">http://www.rabbitmq.com</a> or the purchase the book <a href="http://rabbitmqinaction.com/">RabbitMQ in Action</a> by Alvaro Videla and Jason Williams.&nbsp; I hope you enjoyed the series.</p>
<p>&nbsp;</p>
<p>Footnotes:</p>
<p><a name="Footnote_1">1</a> – See <a href="http://www.rabbitmq.com/amqp-0-9-1-errata.html#section_3">http://www.rabbitmq.com/amqp-0-9-1-errata.html#section_3</a> and <a href="http://hg.rabbitmq.com/rabbitmq-dotnet-client/diff/4def852523e2/projects/client/RabbitMQ.Client/src/client/impl/WireFormatting.cs">http://hg.rabbitmq.com/rabbitmq-dotnet-client/diff/4def852523e2/projects/client/RabbitMQ.Client/src/client/impl/WireFormatting.cs</a> for supported field types.</p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/4pnFJtQMDhc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/05/29/rabbitmq-for-windows-headers-exchanges/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/05/29/rabbitmq-for-windows-headers-exchanges/</feedburner:origLink></item>
		<item>
		<title>RabbitMQ for Windows: Topic Exchanges</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/lx63Dhs6P_c/</link>
		<comments>http://lostechies.com/derekgreer/2012/05/18/rabbitmq-for-windows-topic-exchanges/#comments</comments>
		<pubDate>Fri, 18 May 2012 15:31:06 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=781</guid>
		<description><![CDATA[This is the seventh installment to the series: RabbitMQ for Windows.&#160; In the last installment, we walked through creating a fanout exchange example.&#160; In this installment, we’ll be walking through a topic exchange example. Topic exchanges are similar to direct&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/05/18/rabbitmq-for-windows-topic-exchanges/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the seventh installment to the series: RabbitMQ for Windows.&nbsp; In the <a href="http://lostechies.com/derekgreer/2012/05/16/rabbitmq-for-windows-fanout-exchanges/">last installment</a>, we walked through creating a fanout exchange example.&nbsp; In this installment, we’ll be walking through a topic exchange example.</p>
<p>Topic exchanges are similar to direct exchanges in that they use a routing key to determine which queue a message should be delivered to, but they differ in that they provide the ability to match on portions of a routing key.&nbsp; When publishing to a topic exchange, a routing key consisting of multiple words separated by periods (e.g. “word1.word2.word3”) will be matched against a pattern supplied by the binding queue.&nbsp; Patterns may contain an asterisk (“*”) to match a word in a specific segment or a hash (“#”) to match zero or more words.&nbsp; As discussed earlier in the series, the topic exchange type can be useful for directing messages based on multiple categories or for routing messages originating from multiple sources.</p>
<p>To demonstrate topic exchanges, we’ll return to our logging example, but this time we’ll subscribe to a subset of the messages being published to demonstrate the flexibility of how routing keys are used by topic exchanges.&nbsp; For this example, we’ll be modeling a scenario where a company may have multiple client installations, each of which may be used to service different sectors of a company’s business model (e.g. Business or Personal sectors).&nbsp; We’ll use a routing key that specifies the sector and subscribe to messages published for the Personal sector only.</p>
<p>As with our previous examples, we’ll keep things simple by creating console applications for a Producer and a Consumer.&nbsp; Let’s start by creating the Producer app and establishing a connection using the default settings:</p>
<pre class="prettyprint">using RabbitMQ.Client;

namespace Producer
{
  class Program
  {
    const long ClientId = 10843;

    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
    }
  }
}
</pre>
<p>&nbsp;</p>
<p>Rather than just publishing messages directly from the Main() method as with our first logging example, let’s create a separate logger object this time.&nbsp; Here the logger interface and implementation we’ll be using:</p>
<pre class="prettyprint">  interface ILogger
  {
    void Write(Sector sector, string entry, TraceEventType traceEventType);
  }

  class RabbitLogger : ILogger, IDisposable
  {
    readonly long _clientId;
    readonly IModel _channel;
    bool _disposed;

    public RabbitLogger(IConnection connection, long clientId)
    {
      _clientId = clientId;
      _channel = connection.CreateModel();
      _channel.ExchangeDeclare("direct-exchange-example", ExchangeType.Topic, false, true, null);
    }

    public void Dispose()
    {
      if (!_disposed)
      {
        if (_channel != null &amp;&amp; _channel.IsOpen)
        {
          _channel.Close();
        }
      }
      GC.SuppressFinalize(this);
    }

    public void Write(Sector sector, string entry, TraceEventType traceEventType)
    {
      byte[] message = Encoding.UTF8.GetBytes(entry);
      string routingKey = string.Format("{0}.{1}.{2}", _clientId, sector.ToString(), traceEventType.ToString());
      _channel.BasicPublish("topic-exchange-example", routingKey, null, message);
    }

    ~RabbitLogger()
    {
      Dispose();
    }
  }
</pre>
<p>In addition to an open IConnection, our RabbitLogger class is instantiated with a client Id.&nbsp; We use this as part of the routing key.&nbsp; Since each log can vary by sector, we pass a Sector enum as part of the Write() method.&nbsp; Here’s our Sector enum:</p>
<pre class="prettyprint">  public enum Sector
  {
    Personal,
    Business
  }
</pre>
<p>Returning to our Main() method, we now need to instantiate our RabbitLogger and log messages with differing sectors.&nbsp; As as way to ensure our client has an opportunity to subscribe to our messages and to help emulate a continual stream of log messages being published, let’s use the logger to publish a series of log messages every second for 10 seconds:</p>
<pre class="prettyprint">      TimeSpan time = TimeSpan.FromSeconds(10);
      var stopwatch = new Stopwatch();
      Console.WriteLine("Running for {0} seconds", time.ToString("ss"));
      stopwatch.Start();

      while (stopwatch.Elapsed &lt; time)
      {
        using (var logger = new RabbitLogger(connection, ClientId))
        {
          Console.Write("Time to complete: {0} seconds\r", (time - stopwatch.Elapsed).ToString("ss"));
          logger.Write(Sector.Personal, "This is an information message", TraceEventType.Information);
          logger.Write(Sector.Business, "This is an warning message", TraceEventType.Warning);
          logger.Write(Sector.Business, "This is an error message", TraceEventType.Error);
          Thread.Sleep(1000);
        }
      }
</pre>
<p>This code prints out the time remaining just to give us a little feedback on the publishing progress.&nbsp; Finally, we’ll close our our connection and prompt the user to exit the console application:</p>
<pre class="prettyprint">      connection.Close();
      Console.Write("                             \r");
      Console.WriteLine("Press any key to exit");
      Console.ReadKey();
</pre>
<p>&nbsp;</p>
<p>Here’s the full Producer listing:</p>
<pre class="prettyprint">using System;
using System.Diagnostics;
using System.Text;
using System.Threading;
using RabbitMQ.Client;

namespace Producer
{
  public enum Sector
  {
    Personal,
    Business
  }

  interface ILogger
  {
    void Write(Sector sector, string entry, TraceEventType traceEventType);
  }

  class RabbitLogger : ILogger, IDisposable
  {
    readonly long _clientId;
    readonly IModel _channel;
    bool _disposed;

    public RabbitLogger(IConnection connection, long clientId)
    {
      _clientId = clientId;
      _channel = connection.CreateModel();
      _channel.ExchangeDeclare("direct-exchange-example", ExchangeType.Topic, false, true, null);
    }

    public void Dispose()
    {
      if (!_disposed)
      {
        if (_channel != null &amp;&amp; _channel.IsOpen)
        {
          _channel.Close();
        }
      }
      GC.SuppressFinalize(this);
    }

    public void Write(Sector sector, string entry, TraceEventType traceEventType)
    {
      byte[] message = Encoding.UTF8.GetBytes(entry);
      string routingKey = string.Format("{0}.{1}.{2}", _clientId, sector.ToString(), traceEventType.ToString());
      _channel.BasicPublish("topic-exchange-example", routingKey, null, message);
    }

    ~RabbitLogger()
    {
      Dispose();
    }
  }

  class Program
  {
    const long ClientId = 10843;

    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();

      TimeSpan time = TimeSpan.FromSeconds(10);
      var stopwatch = new Stopwatch();
      Console.WriteLine("Running for {0} seconds", time.ToString("ss"));
      stopwatch.Start();

      while (stopwatch.Elapsed &lt; time)
      {
        using (var logger = new RabbitLogger(connection, ClientId))
        {
          Console.Write("Time to complete: {0} seconds\r", (time - stopwatch.Elapsed).ToString("ss"));
          logger.Write(Sector.Personal, "This is an information message", TraceEventType.Information);
          logger.Write(Sector.Business, "This is an warning message", TraceEventType.Warning);
          logger.Write(Sector.Business, "This is an error message", TraceEventType.Error);
          Thread.Sleep(1000);
        }
      }

      connection.Close();
      Console.Write("                             \r");
      Console.WriteLine("Press any key to exit");
      Console.ReadKey();
    }
  }
}
</pre>
<p>&nbsp;</p>
<p>For our Consumer app, we’ll pretty much be using the same code as with our fanout exchange example, but we’ll need to change the exchange type along with the exchange and queue names.&nbsp; Additionally, we also need to provide a routing key that registers for logs in the Personal sector only.&nbsp; The messages published by the Producer will be in the form: [client Id].[sector].[log severity], so we can use a routing key of “*.Personal.*” (or alternately “*.Personal.#”).&nbsp; Here’s the full Consumer listing:</p>
<pre class="prettyprint">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("topic-exchange-example", ExchangeType.Topic, false, true, null);
      channel.QueueDeclare("log", false, false, true, null);
      channel.QueueBind("log", "topic-exchange-example", "*.Personal.*");

      var consumer = new QueueingBasicConsumer(channel);
      channel.BasicConsume("log", true, consumer);

      while (true)
      {
        try
        {
          var eventArgs = (BasicDeliverEventArgs) consumer.Queue.Dequeue();
          string message = Encoding.UTF8.GetString(eventArgs.Body);
          Console.WriteLine(string.Format("{0} - {1}", eventArgs.RoutingKey, message));
        }
        catch (EndOfStreamException)
        {
          // The consumer was cancelled, the model closed, or the connection went away.
          break;
        }
      }

      channel.Close();
      connection.Close();
    }
  }
}
</pre>
<p>&nbsp;</p>
<p>Setting the solution to run both the Producer and Consumer on startup, we should see similar output to the following listings:</p>
<p>&nbsp;</p>
<p><strong>Producer</strong></p>
<pre class="prettyprint">Running for 10 seconds
Time to complete: 06 seconds
</pre>
<p>&nbsp;</p>
<p><strong>Consumer</strong></p>
<pre class="prettyprint">10843.Personal.Information - This is an information message
10843.Personal.Information - This is an information message
10843.Personal.Information - This is an information message
10843.Personal.Information - This is an information message
10843.Personal.Information - This is an information message
10843.Personal.Information - This is an information message
10843.Personal.Information - This is an information message
</pre>
<p>&nbsp;</p>
<p>This concludes our topic exchange example.&nbsp; Next time, we’ll walk through an example using the final exchange type: Header Exchanges.</p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/lx63Dhs6P_c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/05/18/rabbitmq-for-windows-topic-exchanges/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/05/18/rabbitmq-for-windows-topic-exchanges/</feedburner:origLink></item>
		<item>
		<title>RabbitMQ for Windows: Fanout Exchanges</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/Q6L3t_9tnaQ/</link>
		<comments>http://lostechies.com/derekgreer/2012/05/16/rabbitmq-for-windows-fanout-exchanges/#comments</comments>
		<pubDate>Wed, 16 May 2012 13:24:24 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=767</guid>
		<description><![CDATA[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&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/05/16/rabbitmq-for-windows-fanout-exchanges/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the sixth installment to the series: RabbitMQ for Windows.  In the <a href="http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/">last installment</a>, we walked through creating a direct exchange example and introduced the push API.  In this installment, we’ll walk through a fanout exchange example.</p>
<p>As discussed earlier in the series, the fanout exchange type is useful for facilitating the <a href="http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">publish-subscribe</a> 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.</p>
<p>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.</p>
<p>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.</p>
<p>We’ll start our Producer app as before by establishing a connection using the default settings, creating the connection, and creating a channel:</p>
<pre class="prettyprint">
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();
    }
  }
}
</pre>
<p>Next, we need to declare an exchange of type “fanout”.  We’ll name our new exchange “fanout-exchange-example”:</p>
<pre class="prettyprint">
channel.ExchangeDeclare("fanout-exchange-example", ExchangeType.Fanout, false, true, null);
</pre>
<p>To publish the stock messages periodically, we’ll call a PublishQuotes() method with the provided channel and run it on a background thread:</p>
<pre class="prettyprint">
var thread = new Thread(() => PublishQuotes(channel));
thread.Start();
</pre>
<p>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:</p>
<pre class="prettyprint">
Console.WriteLine("Press 'x' to exit");
var input = (char) Console.Read();
_cancelling = true;
</pre>
<p>Lastly, we need to close the channel and connection:</p>
<pre class="prettyprint">
channel.Close();
connection.Close();
</pre>
<p>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]:</p>
<pre class="prettyprint">
static void PublishQuotes(IModel channel)
{
  while (true)
  {
    if (_cancelling) return;
    IEnumerable<string> quotes = FetchStockQuotes(new[] {"GOOG", "HD", "MCD"});
    foreach (string quote in quotes)
    {
      byte[] message = Encoding.UTF8.GetBytes(quote);
      channel.BasicPublish("fanout-exchange-example", "", null, message);
    }
    Thread.Sleep(5000);
  }
}
</pre>
<p>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:</p>
<pre class="prettyprint">
static IEnumerable&lt;string> FetchStockQuotes(string[] symbols)
{
  var quotes = new List&lt;string>();

  string url = string.Format("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20({0})&#038;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;
}
</pre>
<p>Here is the complete Producer listing:</p>
<pre class="prettyprint">
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("fanout-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<string> quotes = FetchStockQuotes(new[] {"GOOG", "HD", "MCD"});
        foreach (string quote in quotes)
        {
          byte[] message = Encoding.UTF8.GetBytes(quote);
          channel.BasicPublish("fanout-exchange-example", "", null, message);
        }
        Thread.Sleep(5000);
      }
    }


    static IEnumerable&lt;string> FetchStockQuotes(string[] symbols)
    {
      var quotes = new List&lt;string>();

      string url = string.Format("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20({0})&#038;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;
    }
  }
}
</pre>
<p>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:</p>
<pre class="prettyprint">
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("fanout-exchange-example", ExchangeType.Fanout, false, true, null);
      channel.QueueDeclare("quotes", false, false, true, null);
      channel.QueueBind("quotes", "fanout-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();
    }
  }
}
</pre>
<p>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:</p>
<pre class="prettyprint">
GOOG:611.62
HD:48.66
MCD:91.06
GOOG:611.58
HD:48.66
MCD:91.06
</pre>
<p>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”:</p>
<pre class="prettyprint">
channel.QueueBind("quotes", "fanout-exchange-example", "anything");
</pre>
<p>Running the application again shows the same values:</p>
<pre class="prettyprint">
GOOG:611.62
HD:48.66
MCD:91.06
GOOG:611.58
HD:48.66
MCD:91.06 
</pre>
<p>That concludes our fanout exchange example.  Next time, we’ll take a look at the topic exchange type.</p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/Q6L3t_9tnaQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/05/16/rabbitmq-for-windows-fanout-exchanges/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/05/16/rabbitmq-for-windows-fanout-exchanges/</feedburner:origLink></item>
		<item>
		<title>RabbitMQ for Windows: Direct Exchanges</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/4ShCgkOTDgk/</link>
		<comments>http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 12:00:00 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=743</guid>
		<description><![CDATA[This is the fifth installment to the series: RabbitMQ for Windows.&#160; In the last installment, we took a look at the four exchange types provided by RabbitMQ: Direct, Fanout, Topic, and Headers.&#160; In this installment we’ll walk through an example&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the fifth installment to the series: RabbitMQ for Windows.&nbsp; In the<a href="http://lostechies.com/derekgreer/2012/03/28/rabbitmq-for-windows-exchange-types/"> last installment</a>, we took a look at the four exchange types provided by RabbitMQ: Direct, Fanout, Topic, and Headers.&nbsp; In this installment we’ll walk through an example which uses a direct exchange type directly and we’ll take a look at the push API.
<p>In the Hello World example from the second installment of the series, we used a direct exchange type implicitly by taking advantage of the automatic&nbsp; binding of queues to the default exchange using the queue name as the routing key.&nbsp; The example we’ll work through this time will be similar, but we’ll declare and bind to the exchange explicitly.
<p>This time our example will be a distributed logging application.&nbsp; We’ll create a Producer console application which publishes a logging message for some noteworthy action and a Consumer console application which displays the message to the console.
<p>Beginning with our Producer app, we’ll start by establishing a connection using the default settings, create the connection, and create a channel:
<pre class="prettyprint">using RabbitMQ.Client;

namespace Producer
{
  class Program
  {
    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();
    }
  }
}
</pre>
<p>Next, we need to declare the exchange we’ll be publishing our message to.&nbsp; We need to give our exchange a name in order to reference it later, so let’s use “direct-exchange-example”:
<pre class="prettyprint">channel.ExchangeDeclare("direct-exchange-example", ExchangeType.Direct);
</pre>
<p>The second parameter indicates the exchange type.&nbsp; For the official RabbitMQ .Net client, this is just a simple string containing one of the values: direct, fanout, topic, or headers.&nbsp; The type RabbitMQ.Client.ExchangeType defines each of the exchange types as a constant for convenience. </p>
<p>Next, let’s call some method which might produce a value worthy of interest.&nbsp; We’ll call the method DoSomethingInteresting() and have it return a string value:
<pre class="prettyprint">string value = DoSomethingInteresting();
</pre>
<p>For the return value, the implementation of DoSomethingInteresting() can just return the string value of a new Guid:
<pre class="prettyprint">static string DoSomethingInteresting() 
{ 
  return Guid.NewGuid().ToString(); 
} 
</pre>
<p>Next, let’s use the returned value to create a log message containing a severity level of Information:
<pre class="prettyprint">string logMessage = string.Format("{0}: {1}", TraceEventType.Information, value); 
</pre>
<p>Next, we need to convert our log message to a byte array and publish the message to our new exchange:
<pre class="prettyprint"><p>byte[] message = Encoding.UTF8.GetBytes(logMessage);
channel.BasicPublish("direct-exchange-example", "", null, message); 
</p></pre>
<p>Here, we use an empty string as our routing key and null for our message properties. </p>
<p>We end our Producer by closing the channel and connection:
<pre class="prettyprint">channel.Close(); 
connection.Close(); 
</pre>
<p>Here’s the full listing:
<pre class="prettyprint">using System;
using System.Diagnostics;
using System.Text;
using System.Threading;
using RabbitMQ.Client;

namespace Producer
{
  class Program
  {
    static void Main(string[] args)
    {
      Thread.Sleep(1000);
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();

      channel.ExchangeDeclare("direct-exchange-example", ExchangeType.Direct);
      string value = DoSomethingInteresting();
      string logMessage = string.Format("{0}: {1}", TraceEventType.Information, value);

      byte[] message = Encoding.UTF8.GetBytes(logMessage);
      channel.BasicPublish("direct-exchange-example", "", null, message);

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

    static string DoSomethingInteresting()
    {
      return Guid.NewGuid().ToString();
    }
  }
}
</pre>
<p>Note that our logging example’s Producer differs from our Hello World’s Producer in that we didn’t declare a queue this time.&nbsp; In our Hello World example, we needed to run our Producer before the Consumer since the Consumer simply retrieved a single message and exited.&nbsp; Had we published to the default exchange without declaring the queue first, our message would simply have been discarded by the server before the Consumer had an opportunity to declare and bind the queue. </p>
<p>Next, we’ll create our Consumer which starts the same way as our Producer code:
<pre class="prettyprint">using RabbitMQ.Client;

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.Direct);
    }
  }
}
</pre>
<p>Next, we need to declare a queue to bind to our exchange.&nbsp; Let’s name our queue “logs”:
<pre class="prettyprint"> 
channel.QueueDeclare("logs", false, false, true, null); 
</pre>
<p>To associate our logs queue with our exchange, we use the QueueBind() method providing the name of the queue, the name of the exchange, and the binding key to filter messages on:
<pre class="prettyprint">channel.QueueBind("logs", "direct-exchange-example", "");
</pre>
<p>At this point we could consume messages using the pull API method BasicGet() as we did in the Hello World example, but this time we’ll use the push API.&nbsp; To have messages pushed to us rather than us pulling messages, we first need to declare a consumer:
<pre class="prettyprint">var consumer = new QueueingBasicConsumer(channel);
</pre>
<p>To start pushing messages to our consumer, we call the channel’s BasicConsume() method and tell it which consumer to start pushing messages to:
<pre class="prettyprint">channel.BasicConsume(“logs”, true, consumer); 
</pre>
<p>Here, we specify the queue to consume messages from, a boolean flag instructing messages to be auto-acknowledged (see discussion in the Getting the Message section of <a href="http://lostechies.com/derekgreer/2012/03/18/rabbitmq-for-windows-hello-world-review/">Hello World Review</a>), and the consumer to push the messages to.&nbsp;&nbsp;
<p>Now, any messages placed on the queue will automatically be retrieved and placed in a local in-memory queue.&nbsp; To dequeue a message from the local queue, we call the Dequeue() method on the consumer’s Queue property:
<pre class="prettyprint">var eventArgs = (BasicDeliverEventArgs)consumer.Queue.Dequeue(); 
</pre>
<p>This method call blocks until a message is available to be dequeued, or until an EndOfStreamException is thrown indicating that the consumer was cancelled, the channel was closed, or the connection otherwise was terminated. </p>
<p>Once the Dequeue() method returns, the BasicDeliverEventArgs contains the bytes published from the Producer in the Body property, so we can convert this value back into a string and print it to the console:
<pre class="prettyprint">var message = Encoding.UTF8.GetString(eventArgs.Body);
Console.WriteLine(message); 
</pre>
<p>We end our Consumer by closing the channel and connection:
<pre class="prettyprint">channel.Close();
connection.Close(); 
</pre>
<p>Here’s the full listing:
<pre class="prettyprint">using System;
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.Direct);
      channel.QueueDeclare("logs", false, false, true, null);
      channel.QueueBind("logs", "direct-exchange-example", "");

      var consumer = new QueueingBasicConsumer(channel);
      channel.BasicConsume("logs", true, consumer);

      var eventArgs = (BasicDeliverEventArgs) consumer.Queue.Dequeue();

      string message = Encoding.UTF8.GetString(eventArgs.Body);
      Console.WriteLine(message);

      channel.Close();
      connection.Close();
      Console.ReadLine();
    }
  }
}
</pre>
<p>If we run the resulting Consumer.exe at this point, it will block until a message is routed to the queue.&nbsp; Running the Producer.exe from another shell produces a message on the consumer console similar to the following:
<pre class="prettyprint">Information: 610fe447-bf31-41d2-ae29-414b2d00087b 
</pre>
<div class="note">Note: For a convenient way to execute both the Consumer and Producer from within Visual Studio, go to the solution properties and choose “Set StartUp Projects …”.&nbsp; Select the “Multiple startup projects:” option and set both the Consumer and Producer to the Action: Start.&nbsp; Use the arrows to the right of the projects to ensure the Consumer is started before the Producer.&nbsp; In some cases, this can still result in the Producer publishing the message before the Consumer has time to declare and bind the queue, so putting a Thread.Sleep(1000) at the start of your Producer should ensure things happen in the required order.&nbsp; After this, you can run your examples by using Ctrl+F5 (which automatically prompts to exit). </div>
<p>That concludes our direct exchange example.&nbsp; Next time, we’ll take a look at the Fanout exchange type.</p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/4ShCgkOTDgk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/04/02/rabbitmq-for-windows-direct-exchanges/</feedburner:origLink></item>
		<item>
		<title>RabbitMQ for Windows: Exchange Types</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/_zCdtCx7rH0/</link>
		<comments>http://lostechies.com/derekgreer/2012/03/28/rabbitmq-for-windows-exchange-types/#comments</comments>
		<pubDate>Thu, 29 Mar 2012 00:58:38 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=717</guid>
		<description><![CDATA[This is the fourth installment to the series: RabbitMQ for Windows.&#160; In the last installment, we reviewed our Hello World example and introduced the concept of Exchanges.&#160; In this installment, we’ll discuss the four basic types of RabbitMQ exchanges. Exchange&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/03/28/rabbitmq-for-windows-exchange-types/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the fourth installment to the series: RabbitMQ for Windows.&nbsp; In the<a href="http://lostechies.com/derekgreer/2012/03/18/rabbitmq-for-windows-hello-world-review/"> last installment</a>, we reviewed our Hello World example and introduced the concept of Exchanges.&nbsp; In this installment, we’ll discuss the four basic types of RabbitMQ exchanges.<br />
<h2>Exchange Types</h2>
<p>Exchanges control the routing of messages to queues.&nbsp; Each exchange type defines a specific routing algorithm which the server uses to determine which bound queues a published message should be routed to.
<p>RabbitMQ provides four types of exchanges: Direct, Fanout, Topic, and Headers.<br />
<h3>Direct Exchanges </h3>
<p>The Direct exchange type routes messages with a routing key equal to the routing key declared by the binding queue.&nbsp; The following illustrates how the direct exchange type works:
<p>&nbsp; <a href="http://lostechies.com/derekgreer/files/2012/03/DirectExchange1.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DirectExchange" border="0" alt="DirectExchange" src="http://lostechies.com/derekgreer/files/2012/03/DirectExchange_thumb1.png" width="600" height="219"></a>
<p>&nbsp;
<p>The Direct exchange type is useful when you would like to distinguish messages published to the same exchange using a simple string identifier.&nbsp; This is the type of exchange that was used in our Hello World example.&nbsp; As discussed in part 3 of our series, every queue is automatically bound to a default exchange using a routing key equal to the queue name.&nbsp; This default exchange is declared as a Direct exchange.&nbsp; In our example, the queue named “hello-world-queue” was bound to the default exchange with a routing key of “hello-world-queue”, so publishing a message to the default exchange (identified with an empty string) routed the message to the queue named “hello-world-queue”.<br />
<h3>Fanout Exchanges</h3>
<p>The Fanout exchange type routes messages to all bound queues indiscriminately.&nbsp; If a routing key is provided, it will simply be ignored.&nbsp; The following illustrates how the fanout exchange type works:
<p>&nbsp;
<p><a href="http://lostechies.com/derekgreer/files/2012/03/FanoutExchange2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="FanoutExchange" border="0" alt="FanoutExchange" src="http://lostechies.com/derekgreer/files/2012/03/FanoutExchange_thumb2.png" width="600" height="220"></a>
<p>&nbsp;
<p>The Fanout exchange type is useful for facilitating the <a href="http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">publish-subscribe pattern</a>.&nbsp; When using the fanout exchange type, different queues can be declared to handle messages in different ways.&nbsp; For instance, a message indicating a customer order has been placed might be received by one queue whose consumers fulfill the order, another whose consumers update a read-only history of orders, and yet another whose consumers record the order for reporting purposes.<br />
<h3>Topic Exchanges</h3>
<p>The Topic exchange type routes messages to queues whose routing key matches all, or a portion of a routing key.&nbsp; With topic exchanges, messages are published with routing keys containing a series of words separated by a dot (e.g. “word1.word2.word3”).&nbsp; Queues binding to a topic exchange supply a matching pattern for the server to use when routing the message.&nbsp; Patterns may contain an asterisk (“*”) to match a word in a specific position of the routing key, or a hash (“#”) to match zero or more words.&nbsp; For example, a message published with a routing key of “honda.civic.navy” would match queues bound with “honda.civic.navy”, “*.civic.*”, “honda.#”, or “#”, but would not match “honda.accord.navy”, “honda.accord.silver”, “*.accord.*”, or “ford.#”.&nbsp; The following illustrates how the fanout exchange type works:
<p>&nbsp;
<p><a href="http://lostechies.com/derekgreer/files/2012/03/TopicExchange2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="TopicExchange" border="0" alt="TopicExchange" src="http://lostechies.com/derekgreer/files/2012/03/TopicExchange_thumb2.png" width="600" height="220"></a>
<p>&nbsp;
<p>The Topic exchange type is useful for directing messages based on multiple categories (e.g. product type and shipping preference ), or for routing messages originating from multiple sources (e.g. logs containing an application name and severity level).<br />
<h3>Headers Exchanges</h3>
<p>The Headers exchange type routes messages based upon a matching of message headers to the expected headers specified by the binding queue.&nbsp; The headers exchange type is similar to the topic exchange type in that more than one criteria can be specified as a filter, but the headers exchange differs in that its criteria is expressed in the message headers as opposed to the routing key, may occur in any order, and may be specified as matching any or all of the specified headers.&nbsp; The following illustrates how the headers exchange type works:
<p>&nbsp;
<p><a href="http://lostechies.com/derekgreer/files/2012/03/HeadersExchange2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="HeadersExchange" border="0" alt="HeadersExchange" src="http://lostechies.com/derekgreer/files/2012/03/HeadersExchange_thumb2.png" width="600" height="220"></a>
<p>&nbsp;
<p>The Headers exchange type is useful for directing messages which may contain a subset of known criteria where the order is not established and provides a more convenient way of matching based upon the use of complex types as the matching criteria (i.e. a serialized object).<br />
<h2>Conclusion</h2>
<p>That wraps up our introduction to each of the exchange types.&nbsp; Next time, we’ll walk through an example which demonstrates declaring a direct exchange explicitly and take a look at the the push API.  </b></p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/_zCdtCx7rH0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/03/28/rabbitmq-for-windows-exchange-types/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/03/28/rabbitmq-for-windows-exchange-types/</feedburner:origLink></item>
		<item>
		<title>RabbitMQ for Windows: Hello World Review</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/JGZLkXZh7Ns/</link>
		<comments>http://lostechies.com/derekgreer/2012/03/18/rabbitmq-for-windows-hello-world-review/#comments</comments>
		<pubDate>Sun, 18 Mar 2012 22:12:58 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=700</guid>
		<description><![CDATA[This is the third installment to the series: RabbitMQ for Windows.&#160; In the last installment, we discussed some basic messaging concepts and created our first RabbitMQ application.&#160; In this installment, we’ll be taking a closer look at our Hello World&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/03/18/rabbitmq-for-windows-hello-world-review/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the third installment to the series: RabbitMQ for Windows.&nbsp; In the <a href="http://lostechies.com/derekgreer/2012/03/07/rabbitmq-for-windows-building-your-first-application/">last installment</a>, we discussed some basic messaging concepts and created our first RabbitMQ application.&nbsp; In this installment, we’ll be taking a closer look at our Hello World application to help round out our understanding of the basic concepts involved.</p>
<h2>Hello World Review</h2>
<p>In the previous installment, we walked through creating a Hello World example.&nbsp; Let’s review the Producer and Consumer code again:</p>
<p><strong>Producer</strong></p>
<pre class="prettyprint">class Program
{
  static void Main(string[] args)
  {
    var connectionFactory = new ConnectionFactory();
    IConnection connection = connectionFactory.CreateConnection();
    IModel channel = connection.CreateModel();
    channel.QueueDeclare("hello-world-queue", false, false, false, null);
    byte[] message = Encoding.UTF8.GetBytes("Hello, World!");
    channel.BasicPublish(string.Empty, "hello-world-queue", null, message);
    Console.WriteLine("Press any key to exit");
    Console.ReadKey();
    channel.Close();
    connection.Close();
  }
}</pre>
<p><font style="font-weight: bold"></font>&nbsp;</p>
<p><font style="font-weight: bold">Consumer</font></p>
<pre class="prettyprint">class Program
{
  static void Main(string[] args)
  {
    var connectionFactory = new ConnectionFactory();
    IConnection connection = connectionFactory.CreateConnection();
    IModel channel = connection.CreateModel();
    channel.QueueDeclare("hello-world-queue", false, false, false, null);
    BasicGetResult result = channel.BasicGet("hello-world-queue", true);
    if (result != null)
    {
      string message = Encoding.UTF8.GetString(result.Body);
      Console.WriteLine(message);
    }
    Console.WriteLine("Press any key to exit");
    Console.ReadKey();
    channel.Close();
    connection.Close();
  }
}</pre>
<p>&nbsp;</p>
<p>In both the Producer and Consumer projects, we started our Main() method by establishing a Connection to the RabbitMQ server.&nbsp; We then created a Channel to establish a line of communication with the server and declared a Queue to send and receive our messages.&nbsp; In our Producer, we called BasicPublish() to place a message on the queue.&nbsp; In our Consumer, we called BasicGet() to retrieve a message from the queue and print the message to the console.&nbsp; In both the Producer and Consumer projects, we ended the Main() method by closing the channel and connection to the server.</p>
<h2>Establishing the Connection</h2>
<p>Let’s first discuss how our example connects to the RabbitMQ server.&nbsp; In our example, we’re establishing a connection using the default connection settings.</p>
<pre class="prettyprint">var connectionFactory = new ConnectionFactory();</pre>
<p>&nbsp;</p>
<p>This assumes we have a RabbitMQ server running on our local development machine.&nbsp; To connect to this instance, the ConnectionFactory uses a default host name of “localhost” and a default port of 5672.&nbsp; A user name and password must also be provided to connect to the server.&nbsp; When not specified, the ConnectionFactory uses a default user name and password of “guest”.&nbsp; The “guest” user was pre-configured with full administrator rights when we first installed our&nbsp; instance of RabbitMQ.&nbsp; The final parameter of interest is the Virtual Host.&nbsp; RabbitMQ utilizes virtual hosts (i.e. virtual instances of RabbitMQ) to allow multiple projects or teams to manage and secure their own set of queues from within a single RabbitMQ installation. </p>
<p>When we first installed RabbitMQ, a default virtual host named “/” was created.&nbsp; The ConnectionFactory uses this virtual host when one is not specified.</p>
<p>Specified explicitly, we might have configured these default values as follows:</p>
<pre class="prettyprint">var connectionFactory = new ConnectionFactory
                          {
                            HostName = "localhost",
                            Port = 5672,
                            UserName = "guest",
                            Password = "guest",
                            VirtualHost = "/"
                          };
IConnection connection = connectionFactory.CreateConnection();</pre>
<p>&nbsp;</p>
<p>RabbitMQ also supports the <a href="http://www.rabbitmq.com/uri-spec.html">AMQP URI Specification</a> which allows these parameters to be specified as a single URI.&nbsp; Using the URI option, we need to <a href="http://en.wikipedia.org/wiki/Percent-encoding">percent-encode</a> the virtual host as “%2f”.&nbsp; The following is how me might have established our connection using the amqp URI:</p>
<pre class="prettyprint">var connectionFactory = new ConnectionFactory {Uri = "amqp://guest:guest@localhost:5672/%2f"};
IConnection connection = connectionFactory.CreateConnection();</pre>
<h2>&nbsp;</h2>
<h2>Creating a Channel</h2>
<p>After establishing a connection with the server, the next step we take in both the Producer and Consumer projects is to create a Channel.</p>
<pre class="prettyprint">IModel channel = connection.CreateModel();</pre>
<p>&nbsp;</p>
<p>A channel is a light-weight connection used by RabbitMQ to enable multiple communication sessions through a single TCP/IP connection.&nbsp; Operating systems have a limit to the number of TCP/IP connections that can be opened simultaneously, and creating these connections can be relatively expensive.&nbsp; Through the use of channels, we are free to create as many virtual connections with the server as we want without incurring this overhead or being limited by the number of available TCP/IP connections.</p>
<p>Channels are intended to be used for sequencing communication with the server such as declaring queues or the sending and receiving of messages.&nbsp; A single channels should not be used by multiple threads simultaneously. For this reason, it is recommended that channels simply not be shared across threads.</p>
<h2>Declaring the Queue</h2>
<p>After opening a channel within our connection, the next step we take is to declare a Queue. </p>
<pre class="prettyprint">channel.QueueDeclare("hello-world-queue", false, false, false, null);</pre>
<p>&nbsp;</p>
<p>A queue can be thought of as a sort of “mailbox”.&nbsp; Messages put in the mailbox sit there until a recipient retrieves the mail.</p>
<p>In our example, we named our queue “hello-world-queue”.&nbsp; The queue name (along with the RabbitMQ host name and port number) serves as a sort of “mailbox address”.&nbsp; When we publish the encoded string “Hello, World!”, it is placed in the queue named “hello-world-queue’ and awaits until a consumer retrieves and acknowledges the message.</p>
<p>Before discussing the parameters used in our call to QueueDeclare, it will be helpful to take a short detour and discuss how our message actually gets routed from the Producer to the Consumer.</p>
<h2>Message Routing</h2>
<p>When looking at our example, it appears as though the Producer sends our message directly to the “hello-world-queue”.&nbsp; What actually occurs, however, is that the message is routed to the “hello-world-queue” through an Exchange.</p>
<p>When using RabbitMQ, messages aren’t actually published to a queue, but rather are published to an exchange which then routes messages to queues.&nbsp; An exchange can be thought as a “post office”.&nbsp; Just as we don’t generally put mail directly in a recipient&#8217;s mailbox, in RabbitMQ we don’t publish messages directly to a queue.</p>
<p>To receive messages, a queue must first have an exchange binding established.&nbsp; Part of establishing the binding includes specifying which messages should be routed to the queue.&nbsp; In most cases, this is achieved by specifying a routing key which serves as a filter for which messages are delivered to which queues.</p>
<p>The following diagram depicts how messages are published in RabbitMQ:</p>
<p><img src="https://lh5.googleusercontent.com/wUX8EymHUHNBMJt5J8aqrOiyA3UHB0B7nPNTrNr9XDJgvGNehba3y0b-bBNtVDiiLuACOsRYmHI31AMhtrcYB62wVAQHTDrmhxENzWesrg2K7yk-ra8" width="601" height="227"></p>
<p>The reason our code looks like it sends messages directly to the queue is due to the fact that we’re taking advantage of a convenience provided by the RabbitMQ server.&nbsp; Whenever a queue is declared, it is automatically bound to a default exchange with a routing key equal to the queue name.&nbsp; Messages published to the default exchange with a routing key equal to the value of a declared queue name are routed to the associated queue.</p>
<p>In addition to being implicitly bound to all queues, the default exchange also cannot be unbound, deleted, or explicitly declared through code.&nbsp; The only operation that is allowed is the publishing of messages.</p>
<h2>Queue Parameters</h2>
<p>Returning to our discussion of queue declaration, the parameters used in our call to QueueDeclare() creates our queue as a non-durable, non-exclusive, non-auto-deleted queue. </p>
<p>The durability flag pertains to what happens to our queue if the server is restarted.&nbsp; Queues marked as durable will be recreated upon a server restart, while non-durable queues will not be.</p>
<p>The exclusive flag pertains to whether a queue can be declared by more than one channel.&nbsp; Since messages are actually published to exchanges, not queues, there may be cases where you only want a single client instance to be capable of declaring a queue bound to a particular exchange (for example, when using queues to facilitate an RPC call). </p>
<p>Lastly, the auto-delete flag pertains to whether the queue is automatically deleted once all consumers are removed.&nbsp; This flag can be a little misleading since we might suppose setting this to true would cause our “hello-world-queue” to be automatically deleted after our application exists.&nbsp; In fact, it wouldn’t be.</p>
<p>There are two different approaches to receiving messages: pulling and pushing.&nbsp; With the pull API, messages are retrieved on demand through a call to BasicGet().&nbsp; This is the method used in our example.&nbsp; With the pull API, available messages are delivered to a local queue when a Consumer is bound to the channel.&nbsp; When setting the auto-delete flag to true, a queue will be deleted once it detects that all consumers have been removed.&nbsp; While we named the project which receives messages from our queue “Consumer”, the pull API doesn’t actually declare a consumer to retrieve messages.&nbsp; Therefore, the server is never alerted to the fact that the queue is no longer being used.</p>
<h2>Publishing the Message</h2>
<p>The last noteworthy point in our Producer project is the parameters to our call to BasicPublish().</p>
<pre class="prettyprint">channel.BasicPublish(string.Empty, "hello-world-queue", null, message);</pre>
<p>&nbsp;</p>
<p>The first parameter is the name of the exchange to publish the message to.&nbsp; An empty string is the designation for the default exchange discussed earlier in the section on message routing.&nbsp; The second parameter is the routing key.&nbsp; As previously discussed, all queues are bound to the default exchange using a routing key equal to the value of the bound queue name.&nbsp; The third parameter is an instance of IBasicProperties.&nbsp; This class is used to associate a number of properties with the message, such as the message encoding, content-type, and durability.&nbsp; We’ll take a look at some of the uses of this class further in our series.&nbsp; Lastly, the fourth parameter is the byte array representing the message body.</p>
<h2>Getting the Message</h2>
<p>The last noteworthy point in our Consumer project is the parameters to our call to BasicGet().</p>
<pre class="prettyprint">BasicGetResult result = channel.BasicGet("hello-world-queue", true);</pre>
<p>&nbsp;</p>
<p>The first parameter is the queue to pull a message from which should be self-explanatory.&nbsp; The second parameter is a flag which controls the auto-acknowledgement of the message. </p>
<p>When a message is retrieved from a queue with an auto-acknowledge flag set to false, the server holds the message in an unacknowledged state until an acknowledgement or rejection of the message is received on the open channel (note that messages must be accepted or rejected on the same channel they were received on).&nbsp; This is useful when a consumer needs to ensure the message is processed successfully before it’s fully removed from the server.&nbsp; If the channel is closed without receiving an acknowledgment, the message will be requeued and delivered to the next consumer (using pull or get).&nbsp; In the event that a consumer determines it can’t process the message, it can reject the message with a flag indicating whether to requeue the message or not.</p>
<h2>Conclusion</h2>
<p>That’s it for our Hello World example review.&nbsp; Next time, we’ll take a look at the four basic exchange types.</p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/JGZLkXZh7Ns" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/03/18/rabbitmq-for-windows-hello-world-review/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/03/18/rabbitmq-for-windows-hello-world-review/</feedburner:origLink></item>
		<item>
		<title>Dependency Management in .Net: Offline Dependencies with NuGet Command Line Tool</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/0ctGlY71qCQ/</link>
		<comments>http://lostechies.com/derekgreer/2012/03/09/dependency-management-in-net-offline-dependencies-with-nuget-command-line-tool/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 23:13:59 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[NuGet]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=696</guid>
		<description><![CDATA[Today I stumbled upon Scott Haselman’s post: How to access NuGet when NuGet.org is down (or you’re on a plane) in which Scott discusses how he recovered from an issue with the nuget.org site being down during his demo at&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/03/09/dependency-management-in-net-offline-dependencies-with-nuget-command-line-tool/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Today I stumbled upon Scott Haselman’s post: <a href="http://www.hanselman.com/blog/HowToAccessNuGetWhenNuGetorgIsDownOrYoureOnAPlane.aspx" target="_blank">How to access NuGet when NuGet.org is down (or you’re on a plane)</a> in which Scott discusses how he recovered from an issue with the nuget.org site being down during his demo at the Dallas Day of .Net.&nbsp;&nbsp; As it turns out, while NuGet stores packages it downloads in a local Cache folder within your AppData folder, it doesn’t actually use this cache by default.&nbsp; Scott was able to remedy the situation by adding his local cache as a source through the the Visual Studio Package Manager plugin. </p>
<p> Last year, I wrote about my <a href="http://lostechies.com/derekgreer/2011/09/18/dependency-management-in-net/" target="_blank">philosophy for dependency management</a> and&nbsp; <a href="http://lostechies.com/derekgreer/2011/09/20/dependency-management-in-net-using-nuget-without-visual-studio/" target="_blank">how I use NuGet to facilitate dependency management</a> without using the Visual Studio plugin wherein I discuss using the NuGet.exe command line tool to manage .Net dependencies as part of my rake build.&nbsp; After reading Scott’s post, I got to wondering whether the NuGet.exe command line tool also had the same caching issue and after a bit of testing I discovered that it does.&nbsp; Since I, with the help of a former colleague, <a href="http://freshbrewedcode.com/joshbush/" target="_blank">Josh Bush</a>, have evolved the solution I wrote about previously a bit, I thought I’d provide an update to my approach which includes the caching fix.</p>
<p>As discussed in my previous article, I maintain a packages.rb file which serves as a central manifest of all the dependencies used project wide.&nbsp; Here’s one from a recent project:</p>
<pre class="prettyprint">packages = [
[ "Machine.Specifications", "0.5.3.0" ],
[ "ExpectedObjects", "1.0.0.2" ],
[ "Moq", "4.0.10827" ],
[ "RabbitMQ.Client", "2.7.1" ],
[ "log4net", "1.2.11" ]
]

configatron.packages = packages
</pre>
<p>&nbsp;</p>
<p>This is sourced by a rakefile which which is used by a task which installs any packages not already installed.</p>
<p>The basic template I use for my rakefile is as follows:</p>
<pre class="prettyprint">require 'rubygems'
require 'configatron'
 
...

NUGET_CACHE= File.join(ENV['LOCALAPPDATA'], '/NuGet/Cache/') 
FEEDS = ["http://[corporate NuGet Server]:8000", "https://go.microsoft.com/fwlink/?LinkID=206669" ]
require './packages.rb'
 
task :default =&gt; ["build:all"]
 
namespace :build do
 
  task :all =&gt; [:clean, :dependencies, :compile, :specs, :package] 

  ...

  task :dependencies do
    feeds = FEEDS.map {|x|"-Source " + x }.join(' ')
    configatron.packages.each do | name,version |
      feeds = "-Source #{NUGET_CACHE} " + feeds unless !version
        packageExists = File.directory?("#{LIB_PATH}/#{name}")
        versionInfo="#{LIB_PATH}/#{name}/version.info"
        currentVersion=IO.read(versionInfo) if File.exists?(versionInfo)
        if(!packageExists or !version or !versionInfo or currentVersion != version) then
          versionArg = "-Version #{version}" unless !version
          sh "nuget Install #{name} #{versionArg} -o #{LIB_PATH} #{feeds} -ExcludeVersion" do | ok, results |
            File.open(versionInfo, 'w') {|f| f.write(version) } unless !ok
        end
      end
    end
  end
end
</pre>
<p>&nbsp;</p>
<p>This version defines a NUGET_CACHE variable which points to the local cache.&nbsp; In the dependencies task, I join all the feeds into a list of Sources for NuGet to check.&nbsp; I leave out the NUGET_CACHE until I know whether or not a particular package specifies a version number. Otherwise, NuGet would simply check for the latest version which exists within the local cache.</p>
<p>To avoid having to change Visual Studio project references every time I update to a later version of a dependency, I use the –ExcludeVersion option.&nbsp; This means I can’t rely upon the folder name to determine whether the latest version is already installed, so I’ve introduced a version.info file.&nbsp; I imagine this is quite a bit faster than allowing NuGet to determine whether the latest version is installed, but I actually do this for a different reason.&nbsp; If you tell NuGet to install a package into a folder without including the version number as part of the folder and you already have the specified version, <a href="http://nuget.codeplex.com/workitem/1614" target="_blank">it uninstalls and reinstalls the package</a>.&nbsp; Without checking the presence of the correct version beforehand, NuGet would simply reinstall everything every time.</p>
<p>Granted, this rake task is far nastier than it needs to be.&nbsp; It should really only have to be this:</p>
<pre class="prettyprint">  task :dependencies do
    nuget.exe install depedencyManifest.txt –o lib
  end
</pre>
<p>&nbsp;</p>
<p>Where the dependencyManifest file might look a little more like this:</p>
<pre class="prettyprint">Machine.Specifications 0.5.3.0
ExpectedObjects 1.0.0.2
Moq 4.0.10827
RabbitMQ.Client 2.7.1
log4net 1.2.11
</pre>
<p>&nbsp;</p>
<p>Nevertheless, I’ve been able to coerce the tool into doing what I want for the most part and it all works swimmingly once you get it set up.</p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/0ctGlY71qCQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/03/09/dependency-management-in-net-offline-dependencies-with-nuget-command-line-tool/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/03/09/dependency-management-in-net-offline-dependencies-with-nuget-command-line-tool/</feedburner:origLink></item>
		<item>
		<title>RabbitMQ for Windows: Building Your First Application</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/4TKCHfQ5Ig0/</link>
		<comments>http://lostechies.com/derekgreer/2012/03/07/rabbitmq-for-windows-building-your-first-application/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 04:14:58 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=667</guid>
		<description><![CDATA[This is the second installment to the RabbitMQ for Windows series.&#160; In our first installment, we walked through getting RabbitMQ installed on a Microsoft Windows machine. In this installment, we’ll discuss a few high-level concepts and walk through creating our&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/03/07/rabbitmq-for-windows-building-your-first-application/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the second installment to the RabbitMQ for Windows series.&nbsp; In our <a href="http://lostechies.com/derekgreer/2012/03/05/rabbitmq-for-windows-introduction/" target="_blank">first installment</a>, we walked through getting RabbitMQ installed on a Microsoft Windows machine. In this installment, we’ll discuss a few high-level concepts and walk through creating our first RabbitMQ application.</p>
<h2>Basic Concepts</h2>
<p>To being, let’s discuss a few basic concepts. Each of the examples we’ll be working through will have two roles represented: a <em>Producer</em> and a <em>Consumer</em>. A Producer sends messages and a Consumer receives messages. </p>
<p><em>Messages</em> are basically any blob of bytes you’d like to send. This could be a simple ASCII string, JavaScript Object Notation (JSON), or a binary-serialized object. </p>
<p>Messages are sent to <em>Queues</em>.&nbsp; A Queue is a First-In-First-Out (FIFO) data structure. You can think of a queue as a sort of pipe where you put messages in one side of the pipe and the messages arrive at the other end of the pipe.&nbsp; </p>
<p>The following diagram depicts these concepts: </p>
<p>&nbsp;</p>
<p><a href="http://lostechies.com/derekgreer/files/2012/03/ProducerQueueConsumer.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ProducerQueueConsumer" border="0" alt="ProducerQueueConsumer" src="http://lostechies.com/derekgreer/files/2012/03/ProducerQueueConsumer_thumb.png" width="419" height="227"></a></p>
<p>&nbsp;</p>
<p>We’ll introduce other concepts further into the series, but that’s the basics. Let’s move on to creating our first example.</p>
<h2>Hello, World! </h2>
<p>Our first application will be an obligatory “Hello World” example.&nbsp; We’ll create a Publisher application which sends the string “<em>Hello, World!</em>” to a RabbitMQ queue and a Consumer application which receives the message from the queue and displays it to the console.
<p>For all of our examples, we’ll be using the official RabbitMQ .Net client available <a href="http://www.rabbitmq.com/dotnet.html">here</a>.&nbsp; This library is also available via <a href="http://nuget.org/">NuGet</a>, so if you have the <a href="http://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c">NuGet Package Manager</a> installed you can retrieve it through the “Tools-&gt;Library Package Manager” menu item, or if you have the <a href="http://nuget.codeplex.com/releases/view/58939" target="_blank">NuGet.exe command line utility</a> then you can issue the following command in the directory you’d like it installed to:
<p></b>
<pre class="prettyprint">nuget install RabbitMQ.Client
</pre>
<p>&nbsp;</p>
<h3>Create the Producer</h3>
<p>To start, let’s create a new empty solution named HelloWorldExample (File-&gt;New-&gt;Project-&gt;Other Project Types-&gt;Visual Studio Solutions-&gt;Blank Solution). Once you have that created, add a new project of type “Console Application” to the solution and name it “Producer”. </p>
<p>Next, add a reference to the RabbitMQ.Client.dll assembly. </p>
<p>The first thing we’ll need to do for our producer is to establish a connection to the RabbitMQ server using a ConnectionFactory: </p>
<pre class="prettyprint">namespace Producer
{
  class Program
  {
    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
    }
  }
}
</pre>
<p>&nbsp;</p>
<p>The ConnectionFactory has a number of properties that can be set for our connection. In this example, we’re establishing a connection using the default connection settings which assumes you have the RabbitMQ Windows service running on your local development machine. If you’ve installed it on a different machine then you’ll need to set the Host property of the connectionFactory instance to the DNS name where you’ve installed RabbitMQ. </p>
<p>Next, we need to create a Channel: </p>
<pre class="prettyprint">IModel channel = connection.CreateModel();
</pre>
<p>&nbsp;</p>
<p>A channel is a light-weight connection which RabbitMQ uses to enable multiple threads of communication over a single TCP/IP socket. Note that the actual type created is <em>RabbitMQ.Client.IModel</em>. In most RabbitMQ client libraries the term channel is used, but for some reason the authors of the .Net client library chose to use the term “Model”. Descriptive, eh? We’ll use the instance name of “channel” to be more descriptive. </p>
<p>Next, we need to create a queue: </p>
<pre class="prettyprint">channel.QueueDeclare(“hello-world-queue”, false, false, false, null);
</pre>
<p>&nbsp;</p>
<p>This creates a queue on the server named “<em>hello-world-queue</em>” which is non-durable (won’t survive a server restart), is non- exclusive (other channels can connect to the same queue), and is not auto-deleted once it’s no longer being used.&nbsp; We’ll discuss these parameters in more detail further in our series.</p>
<p>Next, we’ll declare a byte array containing a UTF8-encoded array of bytes from the string “Hello, World!” and use the BasicPublish() method to publish the message to the queue: </p>
<pre class="prettyprint">byte[] message = Encoding.UTF8.GetBytes("Hello, World!");
channel.BasicPublish(string.Empty, “hello-world-queue”, null, message);
</pre>
<p>&nbsp;</p>
<p>Again, don’t worry about understanding the parameters just yet. We’ll get to that soon enough. </p>
<p>Finally, we’ll prompt the user to press a key to exit the application and close our channel and connection: </p>
<pre class="prettyprint">Console.WriteLine("Press any key to exit");
Console.ReadKey();
channel.Close();
connection.Close();
</pre>
<p>&nbsp;</p>
<p>Here’s the full Producer listing: </p>
<pre class="prettyprint">using System.Text;
using RabbitMQ.Client;

namespace Producer
{
  class Program
  {
    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();
      channel.QueueDeclare("hello-world-queue", false, false, false, null);
      byte[] message = Encoding.UTF8.GetBytes("Hello, World!");
      channel.BasicPublish(string.Empty, "hello-world-queue", null, message);
      Console.WriteLine("Press any key to exit");
      Console.ReadKey();
      channel.Close();
      connection.Close();
    }
  }
}
</pre>
<p>&nbsp;</p>
<h3>Create the Consumer</h3>
<p>Next, let’s create our Consumer application. Add a new Console Application to the solution named “Consumer” and add a reference to the RabbitMQ.Client assembly. We’ll start our consumer with the same connection, channel, and queue declarations: </p>
<pre class="prettyprint">var connectionFactory = new ConnectionFactory();
IConnection connection = connectionFactory.CreateConnection();
IModel channel = connection.CreateModel();
channel.QueueDeclare("hello-world-queue", false, false, false, null);
</pre>
<p>&nbsp;</p>
<p>Next, we’ll use the BasicGet() method to consume the message from the queue “hello-world-queue”: </p>
<pre class="prettyprint">BasicGetResult result = channel.BasicGet("hello-world-queue", true);
</pre>
<p>&nbsp;</p>
<p>Next, we’ll check to ensure we received a result. If so, we’ll convert the byte array contained within the Body property to a string and display it to the console: </p>
<pre class="prettyprint">if (result != null)
{
  string message = Encoding.UTF8.GetString(result.Body);
  Console.WriteLine(message);
}
</pre>
<p>&nbsp;</p>
<p>Lastly, we’ll prompt the user to press a key to exit the application and close our channel and connection: </p>
<pre class="prettyprint">Console.WriteLine("Press any key to exit");
Console.ReadKey();
channel.Close();
connection.Close();
</pre>
<p>&nbsp;</p>
<p>Here’s the full Consumer listing: </p>
<pre class="prettyprint">using System;
using System.Text;
using RabbitMQ.Client;

namespace Consumer
{
  class Program
  {
    static void Main(string[] args)
    {
      var connectionFactory = new ConnectionFactory();
      IConnection connection = connectionFactory.CreateConnection();
      IModel channel = connection.CreateModel();
      channel.QueueDeclare("hello-world-queue", false, false, false, null);
      BasicGetResult result = channel.BasicGet("hello-world-queue", true);
      if (result != null)
      {
        string message = Encoding.UTF8.GetString(result.Body);
        Console.WriteLine(message);
      }
      Console.WriteLine("Press any key to exit");
      Console.ReadKey();
      channel.Close();
      connection.Close();
    }
  }
}
</pre>
<p>&nbsp;</p>
<p>To see the application in action, start the Publisher application first and then start the Consumer application. If all goes well, you should see the Consumer application print the following:</p>
<pre class="prettyprint">Hello, World!
Press any key to exit
</pre>
<p>&nbsp;</p>
<p>Congratulations! You’ve just completed your first RabbitMQ application.&nbsp; Next time, we&#8217;ll take a closer look at the concepts used within our Hello World example. </p>
<pre></pre>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/4TKCHfQ5Ig0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/03/07/rabbitmq-for-windows-building-your-first-application/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/03/07/rabbitmq-for-windows-building-your-first-application/</feedburner:origLink></item>
		<item>
		<title>RabbitMQ for Windows: Introduction</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/mjEwtHETy-k/</link>
		<comments>http://lostechies.com/derekgreer/2012/03/05/rabbitmq-for-windows-introduction/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 13:00:00 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[RabbitMQ]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=649</guid>
		<description><![CDATA[If you’re interested in getting started with distributed programming and you develop on the Microsoft Windows platform, RabbitMQ may be what you’re looking for.&#160; RabbitMQ is an open source, standards-based, multi-platform message broker with client libraries available for a host&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/03/05/rabbitmq-for-windows-introduction/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you’re interested in getting started with distributed programming and you develop on the Microsoft Windows platform, <a href="http://www.rabbitmq.com" target="_blank">RabbitMQ</a> may be what you’re looking for.&nbsp; RabbitMQ is an open source, standards-based, multi-platform message broker with client libraries available for a host of development platforms including .Net.&nbsp;&nbsp;
<p>This series will provide a gentle introduction to getting started with RabbitMQ for .Net developers, including a Windows environment installation guide along with an introduction to basic concepts and features through the use of examples in C#.&nbsp; In this first installment, we’ll cover installation and basic configuration.<br />
<h2>Installation </h2>
<p>The first thing to know about RabbitMQ installation is that RabbitMQ runs on the <a href="http://en.wikipedia.org/wiki/Erlang_(programming_language)">Erlang</a> virtual runtime.&nbsp; “<em>What is Erlang</em>”, you ask, and “<em>Why should I ask our admins to install yet another runtime engine on our servers</em>”?&nbsp; Erlang is a functional language which places a large emphasis on concurrency and high reliability.&nbsp; Developed by&nbsp; Joe Armstrong, Mike Williams, and Robert Virding to support telephony applications at Ericsson, Erlang’s flagship product, the Ericsson AXD301 switch, is purported to have achieved a reliability of nine <a href="http://en.wikipedia.org/wiki/Nines_(engineering)">&#8220;9&#8243;s</a>.
<p>A popular quote among Erlang adherents is Verding’s “First Rule of Programming”:<br />
<blockquote>
<p>“Any sufficiently complicated concurrent program in another language contains an ad hoc informally-specified bug-ridden slow implementation of half of Erlang.” &#8211; Robert Verding </p>
</blockquote>
<p>Sound like the perfect platform to write a message broker in?&nbsp; The authors of RabbitMQ thought so too.
<p>With that, let’s get started with the installation.<br />
<h3>&nbsp;</h3>
<h3>Step 1: Install Erlang</h3>
<p>The first step will be to download and install Erlang for Windows.&nbsp; You can obtain the latest installer from <a href="http://www.erlang.org/download.html">here</a> (version R15B at the time of this writing) .
<p>After downloading and completing the Erlang installation wizard, you should have a new ERLANG_HOME environment variable set.&nbsp; If not, you’ll want to set this now so RabbitMQ will be able to locate your installation of Erlang.
<p><a href="http://lostechies.com/derekgreer/files/2012/03/ErlangEnv.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="ErlangEnv" border="0" alt="ErlangEnv" src="http://lostechies.com/derekgreer/files/2012/03/ErlangEnv_thumb.png" width="395" height="438"></a>
<p>&nbsp;<br />
<h3>&nbsp;</h3>
<h3>Step 2: Install RabbitMQ</h3>
<p>Next, download and install the latest version of RabbitMQ for Windows from <a href="http://www.rabbitmq.com/download.html">here</a> (version 2.7.1 at the time of this writing).<br />
<h3>&nbsp;</h3>
<h3>Step 3: Install the RabbitMQ Management Plugin </h3>
<p>By default, the RabbitMQ Windows installer registers RabbitMQ as a Windows service, so technically we’re all ready to go.&nbsp; In addition to the command line utilities provided for managing and monitoring our RabbitMQ instance, a Web-based management plugin is also provided with the standard Windows distribution.&nbsp; The following steps detail how to get the management plugin up and going.
<p>First, from an elevated command prompt, change directory to the sbin folder within the RabbitMQ Server installation directory (e.g. %PROGRAMFILES%\RabbitMQ Server\rabbitmq_server_2.7.1\sbin\).
<p>Next, run the following command to enable the rabbitmq management plugin:
<pre class="prettyprint">rabbitmq-plugins.bat enable rabbitmq_management 
</pre>
<p>&nbsp;
<p>Lastly, to enable the management plugin we need to reinstall the RabbitMQ service.&nbsp; Execute the following sequence of commands to reinstall the service:
<pre class="prettyprint"> 
rabbitmq-service.bat stop 
rabbitmq-service.bat install 
rabbitmq-service.bat start 
</pre>
<p>&nbsp;
<p>To verify management plugin is up and running, start your favorite browser and navigate to <a href="http://localhost:55672/mgmt/">http://localhost:55672/mgmt/</a>.&nbsp; If everything went ok, you should see a screen similar to the following: </p>
<p>&nbsp;
<p>&nbsp;<a href="http://lostechies.com/derekgreer/files/2012/03/RabbitManagement.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="RabbitManagement" border="0" alt="RabbitManagement" src="http://lostechies.com/derekgreer/files/2012/03/RabbitManagement_thumb.png" width="640" height="302"></a></p>
<p>From here, you’ll be able to configure and monitor your RabbitMQ instance. </p>
<p>That concludes our installation guide.&nbsp; Next time, we’ll walk through writing our first RabbitMQ C# application.<br />
</b></p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/mjEwtHETy-k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/03/05/rabbitmq-for-windows-introduction/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/03/05/rabbitmq-for-windows-introduction/</feedburner:origLink></item>
		<item>
		<title>JavaScript Closures Explained</title>
		<link>http://feedproxy.google.com/~r/lostechies/aspiringcraftsman/~3/9kstCn9AYzc/</link>
		<comments>http://lostechies.com/derekgreer/2012/02/17/javascript-closures-explained/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 03:40:29 +0000</pubDate>
		<dc:creator>Derek Greer</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Closures]]></category>
		<category><![CDATA[ECMAScript]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://lostechies.com/derekgreer/?p=645</guid>
		<description><![CDATA[If you write any code in JavaScript then you’ve probably used closures, but do you actually understand what they are and how they work?&#160; Taking the time to understand closures and how they’re implemented can add a deeper dimension to&#160;&#8230; <a href="http://lostechies.com/derekgreer/2012/02/17/javascript-closures-explained/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you write any code in JavaScript then you’ve probably used closures, but do you actually understand what they are and how they work?&nbsp; Taking the time to understand closures and how they’re implemented can add a deeper dimension to your understanding of the JavaScript language.&nbsp; In this article, I’ll discuss what closures are and how they’re specified for the JavaScript language.</p>
<h2>What Are Closures?</h2>
<p>A <em>closure</em> is a pairing of a function along with its referencing environment such that identifiers within the function may refer to variables declared within the referencing environment.</p>
<p>Let’s consider the following example:</p>
<pre class="prettyprint">var createGreeting = function(greeting) {
    return function(name) {
        document.write(greeting + ', ' + name + '.');
    };
};


helloGreeting = createGreeting("Hello");
howdyGreeting = createGreeting("Howdy");

helloGreeting("John");  // Hello, John.
helloGreeting("Sally"); // Hello, Sally.
howdyGreeting("John");  // Howdy, John.
howdyGreeting("Sally"); // Howdy, Sally.
</pre>
<p>&nbsp;</p>
<p>In this code, a function named <em>createGreeting</em> is defined which returns an anonymous function.&nbsp; When the anonymous function is executed, it prints a greeting which consists of the outer function’s <em>greeting</em> parameter along with the inner function’s <em>name</em> parameter.&nbsp; While the greeting parameter is neither a formal parameter&nbsp; nor a local variable of the inner function (which is to say it is a <em>free variable</em>), it is still resolved when the function executes.&nbsp; Moreover, the createGreeting function object is no longer in scope and may have even been garbage collected at the point the function executes.&nbsp; How then does this work?</p>
<p>The inner function is capable of resolving the greeting identifier due to a closure which has been formed for the inner function.&nbsp; That is to say, the inner function has been paired with its referencing (as opposed to its calling) environment.</p>
<p>Conceptually, we can think of our closure as the marriage between a function and the environment in which it was declared within:</p>
<p><a href="http://lostechies.com/derekgreer/files/2012/02/closure2.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="closure2" border="0" alt="closure2" src="http://lostechies.com/derekgreer/files/2012/02/closure2_thumb.png" width="329" height="153"></a></p>
<p>&nbsp;</p>
<p>Exactly what this marriage looks like at an implementation level differs depending on the language.&nbsp; In C# for instance, closures are implemented by the instantiation of a compiler-generated class which encapsulates a delegate and the variables referenced by the delegate from its declaring scope. In JavaScript, the function object itself contains a non-accessible property pointing to an object containing the variables from its declaring scope.&nbsp; While each implementation differs, both render a function that has access to what its environment looked like at the point it was created.</p>
<p>Let’s move on to examining how JavaScript closures work from a specification perspective.</p>
<h2>JavaScript Closures</h2>
<p>To understand how closures work in JavaScript, it helps to have a grasp of the underlying concepts set forth within the <a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">ECMAScript Language Specification</a>.&nbsp; I’ll be using Edition 5.1 (ECMA-262) of the specification as the basis for the following discussion.</p>
<h3>Execution Contexts</h3>
<p>When a JavaScript function is executed, a construct referred to as an <em>Execution Context</em> is created.&nbsp; The Execution Context is an abstract concept prescribed by the specification to track the execution progress of its associated code.&nbsp; As an application runs, an initial Global Execution Context is created.&nbsp; As each new function is created, new Execution Contexts are created which form an Execution Context stack.</p>
<p>There are three primary components prescribed for the Execution Context:</p>
<ol>
<ol>
<li>
<p>The LexicalEnvironment</p>
<li>
<p>The VariableEnvironment</p>
<li>
<p>The ThisBinding</p>
</li>
</ol>
</ol>
<p>Only the LexicalEnvironment and VariableEnvironment components are relevant to the topic of closures, so I’ll exclude discussion of the ThisBinding.&nbsp; (For information about how the ThisBinding is used, see sections 10.4.1.1, 10.4.2, and 10.4.3 of the <a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">ECMAScript Lanauage Specification</a>.)</p>
<h3>LexicalEnvironment</h3>
<p>The <em>LexicalEnvironment</em> is used to resolve identifier references made by code associated with the execution context.&nbsp; Conceptually, we can think of the LexicalEnvironment as an object containing the variables and formal parameters declared within the code associated by the current Execution Context.</p>
<p>A LexicalEnvironement itself is comprised of two components: An <em>Environment Record</em>, which is used to store identifier bindings for the Execution Context, and an <em>outer</em> reference which points to a LexicalEnvironment of the declaring Execution Context (which is null in the case of the Global Execution Context’s LexicalEnvironment outer reference).&nbsp; This forms a chain of LexicalEnvironments, each maintaining a reference to the outer scope’s environment:</p>
<p>&nbsp;</p>
<p align="center"><a href="http://lostechies.com/derekgreer/files/2012/02/LexicalEnvironmentChain.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="LexicalEnvironmentChain" border="0" alt="LexicalEnvironmentChain" src="http://lostechies.com/derekgreer/files/2012/02/LexicalEnvironmentChain_thumb.png" width="322" height="483"></a></p>
<p>&nbsp;</p>
<h3>VariableEnvironment</h3>
<p>The <em>VariableEnvironment</em> is used to record the bindings created by&nbsp; variables and function declarations within an execution context.&nbsp; Upon reading that description, you may be thinking: “<em>but I thought the LexicalEnvironment held the bindings for the current execution context</em>”.&nbsp; Technically, the VariableEnvironment contains the bindings of the variables and function declarations defined within an Execution Context and the LexicalEnvironment is used to resolve the bindings within the Execution Context.&nbsp; Confused?&nbsp; The answer to this seemingly incongruous approach is that, in most cases, the LexicalEnvironment and VariableEnvironment are references to the same entity.</p>
<p>The LexicalEnvironment and VariableEnvironment components are actually references to a LexicalEnvironment type.&nbsp; When the JavaScript interpreter enters the code for a function, a new LexicalEnvironment instance is created and is assigned to both the LexicalEnvironment and VariableEnvironment references.&nbsp; The variables and function declarations are then recorded to the VariableEnvironment reference.&nbsp; When the LexicalEnvironment is used to resolve an identifier, any bindings created through the VariableEnvironment reference are available for resolution.</p>
<h3>Identifier Resolution</h3>
<p>As previously discussed, LexicalEnvironments have an outer reference which, except for the Global Execution Context’s LexicalEnvironment, points to a LexicalEnvironment record of the declaring Execution Context (i.e. a function block’s “parent” scope).&nbsp; Functions contain an internal scope property (denoted as [[Scope]] by the ECMAScript specification) which is assigned a LexicalEnvironment from the declaring context.&nbsp; In the case of function expressions (e.g. var doStuff = function() { …}), the [[Scope]] property is assigned to the declaring context’s LexicalEnvironment.&nbsp; In the case of function declarations (e.g. function doStuff() { … }), the [[Scope]] property is assigned to the declaring context’s VariableEnvironment.&nbsp; We’ll discuss the reasons for this disparity shortly, but for now let’s just focus on the fact that the function has a [[Scope]] which points to the environment in which is was created.&nbsp; This is our pairing of a function with its referencing environment, which is to say, this is our closure.&nbsp; </p>
<p>If we recall our previous conceptualization of a function paired with its environment, the JavaScript version of this conceptualization would look a little like this:</p>
<p>&nbsp;</p>
<p align="center"><a href="http://lostechies.com/derekgreer/files/2012/02/closure3.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="closure3" border="0" alt="closure3" src="http://lostechies.com/derekgreer/files/2012/02/closure3_thumb.png" width="546" height="377"></a></p>
<p>When resolving an identifier, the current LexicalEnvironment is passed to an abstract operation named <em>GetIdentiferReference</em> which checks the current LexicalEnvironment’s Environment Record for the requested identifier and if not found calls itself recursively with the LexicalEnvironment’s outer reference.&nbsp; Each link of the chain is checked until the top of the chain is reached (the LexicalEnvironment of the Global Context) in which case the binding is resolved or a reference of undefined is returned.</p>
<h3>A Distinction Without a Difference … Usually</h3>
<p>As mentioned, the LexicalEnvironment and the VariableEnvironement references point to the same LexicalEnvironment instance in most cases.&nbsp; The reason for maintaining these as separate references is to support the <em>with</em> statement.</p>
<p>The <em>with</em> statement facilitates block scope by using a supplied object as the Environment Record for a newly created LexicalEnvironment.&nbsp; Consider the following example:</p>
<pre class="prettyprint">var x = {
    a: 1
};

var doSomething = function() {
    var a = 2;
    
    with(x) {
        console.log(a);
    };
};
doSomething(); // 1
</pre>
<p>&nbsp;</p>
<p>In this code, while the doSomething function assigns the variable a the value of 2, the console.log function logs the value of 1 instead of 2.&nbsp; What is happening here is that, for the enclosing block of code, the with statement is inserting a new LexicalEnvironment at the front of the chain with an Environment Record set to the object x.&nbsp; When the code within the with statement executes, the first LexicalEnvironment to be checked will be the one created by the with statement whose Environment Record contains a binding of x with the value of 1.&nbsp; Once the with statement exits, the LexicalEnvironment of the current Execution Context is restored to its previous state.</p>
<p>According to the ECMAScript specification, function expressions may be declared within a with statement, but not function declarations (though most implementations allow it with varied behavior).&nbsp; Since function expressions may be declared, their declaration should form a closure based upon the declaring environment’s LexicalEnvironment because it is the LexicalEnvironement which might be changed by a with statement.&nbsp; This is the reason why Execution Contexts are prescribed&nbsp; two different LexicalEnvironment references and why function declarations and function expressions differ in which reference their [[Scope]] property is assigned upon function creation.</p>
<h2>Conclusion</h2>
<p>This concludes our exploration of closures in JavaScript.&nbsp; While understanding the ECMAScript Language Specification in detail certainly isn’t necessary to have a working knowledge of closures, I find taking a peek under the covers now and again helps to broaden one’s understanding about a language and its concepts.</p>
<img src="http://feeds.feedburner.com/~r/lostechies/aspiringcraftsman/~4/9kstCn9AYzc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/derekgreer/2012/02/17/javascript-closures-explained/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://lostechies.com/derekgreer/2012/02/17/javascript-closures-explained/</feedburner:origLink></item>
	</channel>
</rss>
