Content based routing means that the routing is done on the whole message body rather than on single property like routing key.
AMQP specification doesn't define full-blown content based routing. There is a good reason for that. Examining complete message - given it can be several megabytes long - would not be computationally viable. The broker would spend just too much time analysing messages and that would create a bottleneck in the network.
AMQP thus separates message into two parts called header and body. Body is the long part of the message and it will never be examined in the process of routing. Header is a short part of the message and it can contain arbitrary properties that can be examined by routing algorithm.
You can think of message headers as of a simple table containing name-value pairs. Imagine that individual messages are describing news items. Then you can have message header filled like this:
With such a header attached to each message, we would expect clients to be able to subscribe for all the investigative articles from France or all the sport-related news from Russia or all the articles written by Jean Valjean etc.
To implement such a routing mechanism headers exchange type should be used. Each message should be accompanied by corresponding header, while each binding between the exchange and subscriber's queue (subscription) should contain a list of name-value pairs describing the messages client would like to receive.
So, for example, binding to get all the investigative articles would look like this:
Binding to get all news items written by Jean Valjean would look like this:
To get all the sport digests from Russia, you would create following binding:
The routing of a message is shown on the following picture. The article matches author=Jean Valjean binding and is delivered to the queue B. It matches type=article & category=investigative binding as well and is delivered to the queue C. However, it doesn't match region=Spain binding and so it isn't delivered to the queue A:
Have a look at the news publishing application implementation here:
Compile the examples:
$ c -l news_publisher.c Compiling news_publisher... Linking news_publisher... $ c -l news_terminal.c Compiling news_terminal... Linking news_terminal... $ c -l subscribe_to_news.c Compiling subscribe_to_news... Linking subscribe_to_news...
Start OpenAMQ broker:
Start the news publishing application:
$ ./news_publisher localhost
Start the news terminal:
$ ./news_terminal localhost johnm
Now, subscribe for a topic you are interested in. The criteria are entered as name-value pairs, i.e. if you want to receive all the messages where type=article and category=science do it like this:
$ ./subscribe_to_news localhost johnm type article category science
At this point the news items should start appearing in your news terminal window.