Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Note
titleArchive Content

Please note this page is present for reference only. These old .Net clients (and related code) have been removed and are no longer released components.

Tutorial

This tutorial consists of a series of examples using the three most commonly used exchange types - Direct, Fanout and Topic
exchanges. These examples show how to write applications that use the most common messaging paradigms.

...

This program is waiting for messages to be published, sex see next step:

4) Publish a series of messages to the amq.direct exchange by running direct producer, as follows:

...

This program is waiting for messages to be published, sex see next step:

4) In a separate window, publish a series of messages to the amq.fanout exchange by running fanout producer, as follows:

...

Code Block
// Create a unique queue name for this consumer by concatenating
// the queue name parameter with the Session ID.     
Console.WriteLine("Declaring queue: " + queue);
session.queueDeclare(queue, Option.EXCLUSIVE, Option.AUTO_DELETE);

// Route messages to the new queue if they match the routing key.
// Also route any messages to with the "control" routing key to
// this queue so we know when it's time to stop. A publisher sends
// a message with the content "That's all, Folks!", using the
// "control" routing key, when it is finished.

session.exchangeBind(queue, "amq.topic", routing_key);
session.exchangeBind(queue, "amq.topic", "control");

// subscribe the listener to the queue
IMessageListener listener = new MessageListener(session);
session.attachMessageListener(listener, queue);
session.messageSubscribe(queue);

Writing Request/Response Applications

In the request/response examples, we write a server that accepts strings from clients and converts them to upper case, sending the result back to the requesting client. This example consists of two programs.

  • Client.cs is a client application that sends messages to the server.
    • Server.cs is a service that accepts messages, converts their content to upper case, and sends the result to the amq.direct exchange, using the request's reply-to property as the routing key for the response.

Running the Request/Response Examples

1) Make sure your PATH contains the directory <home>/qpid/lib

2) Make sure that a qpid broker is running:

Code Block

$ ps -eaf | grep qpidd

If a broker is running, you should see the qpidd process in the output of the above
command.

3) Run the server.

$ cd <home>/qpid/examples/direct

Code Block

With cygwin: 

$ ./example-request-response-Server.exe hostname portnumber

Code Block

or with mono:

$ mono ./example-request-response-Server.exe hostname portnumber

Code Block


You will see output similar to this:

Waiting for requests

Code Block


4) In a separate window, start a client:

$ cd <home>/qpid/examples/direct

With cygwin:

Code Block

$ ./example-request-response-Client.exe [hostname] [portnumber]

or with mono:

Code Block

$ mono ./example-request-response-Client.exe [hostname] [portnumber]

You will see output similar to this:

Code Block

Activating response queue listener for: clientSystem.Byte[]
Waiting for all responses to arrive ...
Response: TWAS BRILLIG, AND THE SLITHY TOVES
Response: DID GIRE AND GYMBLE IN THE WABE.
Response: ALL MIMSY WERE THE BOROGROVES,
Response: AND THE MOME RATHS OUTGRABE.
Shutting down listener for clientSystem.Byte[]
Response: THAT'S ALL, FOLKS!

4) Go back to the server window, the output should be similar to this:

Code Block

Waiting for requests
Request: Twas brillig, and the slithy toves
Request: Did gire and gymble in the wabe.
Request: All mimsy were the borogroves,
Request: And the mome raths outgrabe.
Request: That's all, folks!

Now we will examine the code for each of these programs. In each section, we will discuss only the code that must be added to the skeleton shown in Section "Creating and Closing Sessions".

The Client Application

The first program in the request-response example, Client.cs, sets up a private response queue to receive responses from the server, then sends messages the server, listening to the response queue for the server's responses.

Code Block

string response_queue = "client" + session.getName();
// Use the name of the response queue as the routing key
session.queueDeclare(response_queue);
session.exchangeBind(response_queue, "amq.direct", response_queue);

// Create a listener for the response queue and listen for response messages.
Console.WriteLine("Activating response queue listener for: " + response_queue);
IMessageListener listener = new ClientMessageListener(session);
session.attachMessageListener(listener, response_queue);
session.messageSubscribe(response_queue);

Set some properties that will be used for all requests. The routing key for a request is request.
The reply-to property is set to the routing key for the client's private queue.

Code Block

IMessage request = new Message();
request.DeliveryProperties.setRoutingKey("request");
request.MessageProperties.setReplyTo(new ReplyTo("amq.direct", response_queue));

Now send some requests...

Code Block

string[] strs = {
                 "Twas brillig, and the slithy toves",
                 "Did gire and gymble in the wabe.",
                 "All mimsy were the borogroves,",
                 "And the mome raths outgrabe.",
                 "That's all, folks!"
                };
foreach (string s in strs)
{
 request.clearData();
 request.appendData(Encoding.UTF8.GetBytes(s));
 session.messageTransfer("amq.direct", request);
}

And wait for responses to arrive:

Code Block

Console.WriteLine("Waiting for all responses to arrive ...");
Monitor.Wait(session);

The Server Application

The second program in the request-response example, Server.cs, uses the reply-to property as the routing key for responses.

The main body of Server.cs creates an exclusive queue for requests, then waits for messages to arrive.

Code Block

const string request_queue = "request";
// Use the name of the request queue as the routing key
session.queueDeclare(request_queue);
session.exchangeBind(request_queue, "amq.direct", request_queue);

lock (session)
{
 // Create a listener and subscribe it to the request_queue      
 IMessageListener listener = new MessageListener(session);
 session.attachMessageListener(listener, request_queue);
 session.messageSubscribe(request_queue);
 // Receive messages until all messages are received
 Console.WriteLine("Waiting for requests");
 Monitor.Wait(session);
}

The listener's messageTransfer() method converts the request's content to upper case, then sends a response to the broker, using the request's reply-to property as the routing key for the response.

Code Block

BinaryReader reader = new BinaryReader(request.Body, Encoding.UTF8);
byte[] body = new byte[request.Body.Length - request.Body.Position];
reader.Read(body, 0, body.Length);
ASCIIEncoding enc = new ASCIIEncoding();
string message = enc.GetString(body);
Console.WriteLine("Request: " + message);
            
// Transform message content to upper case
string responseBody = message.ToUpper();

// Send it back to the user
response.clearData();
response.appendData(Encoding.UTF8.GetBytes(responseBody));
_session.messageTransfer("amq.direct", routingKey, response);