summaryrefslogtreecommitdiff
path: root/qpid/doc/book/src/old/NET-User-Guide.xml
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/doc/book/src/old/NET-User-Guide.xml')
-rw-r--r--qpid/doc/book/src/old/NET-User-Guide.xml1383
1 files changed, 0 insertions, 1383 deletions
diff --git a/qpid/doc/book/src/old/NET-User-Guide.xml b/qpid/doc/book/src/old/NET-User-Guide.xml
deleted file mode 100644
index 7bfa20b8c8..0000000000
--- a/qpid/doc/book/src/old/NET-User-Guide.xml
+++ /dev/null
@@ -1,1383 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-
--->
-
-<section>
- <title>
- Apache Qpid: Open Source AMQP Messaging - .NET User Guide
- </title>
- <section role="h1" id="NETUserGuide-Tutorial">
- <title>
- Tutorial
- </title>
- <para>
- 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.
- </para>
- <itemizedlist>
- <listitem>
- <para>direct</para>
- <para>In the direct examples, a message producer writes to the direct
- exchange, specifying a routing key. A message consumer reads
- messages from a named queue. This illustrates clean separation
- of concerns - message producers need to know only the exchange
- and the routing key, message consumers need to know only which
- queue to use on the broker.
- </para>
- </listitem>
- <listitem>
- <para>fanout</para>
- <para>The fanout examples use a fanout exchange and do not use
- routing keys. Each binding specifies that all messages for a
- given exchange should be delivered to a given queue.
- </para>
- </listitem>
- <listitem>
- <para>pub-sub</para>
- <para>In the publish/subscribe examples, a publisher
- application writes messages to an exchange, specifying a
- multi-part key. A subscriber application subscribes to
- messages that match the relevant parts of these keys, using a
- private queue for each subscription.
- </para>
- </listitem>
- <listitem>
- <para>request-response</para>
- <para>In the request/response examples, a simple service accepts
- requests from clients and sends responses back to them. Clients
- create their own private queues and corresponding routing keys.
- When a client sends a request to the server, it specifies its
- own routing key in the reply-to field of the request. The
- server uses the client's reply-to field as the routing key for
- the response.
- </para>
- </listitem>
- </itemizedlist>
- <section role="h2" id="NETUserGuide-RunningtheExamples">
- <title>
- Running the
- Examples
- </title>
- <para>
- Before running the examples, you need to unzip the file
- Qpid.NET-net-2.0-M4.zip, the following tree is created:
- </para>
-
-
- <programlisting>
-&lt;home&gt;
- |-qpid
- |-lib (contains the required dlls)
- |-examples
- |- direct
- | |-example-direct-Listener.exe
- | |-example-direct-Producer.exe
- |- fanout
- | |-example-fanout-Listener.exe
- | |-example-fanout-Producer.exe
- |- pub-sub
- | |-example-pub-sub-Listener.exe
- | |-example-pub-sub-Publisher.exe
- |- request-response
- |-example-request-response-Client.exe
- |-example-request-response-Server.exe
- </programlisting>
-
-
- <para>
- Make sure your PATH contains the directory
- &lt;home&gt;/qpid/lib
- The examples can be run by executing the provided exe files:
- </para>
-
-
- <programlisting>
-$ cd &lt;home&gt;/qpid/examples/examplefolder
-$ example-...-.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- where [hostname] is the qpid broker host name
- (default is localhost) and [portnumber] is the port number on which the
- qpid broker is accepting connection (default is 5672).
- </para>
- <!--h2-->
- </section>
-
- <section role="h2" id="NETUserGuide-CreatingandClosingSessions">
- <title>
- Creating
- and Closing Sessions
- </title>
-
- <para>
- All of the examples have been written using the Apache Qpid .NEt
- 0.10 API. The examples use the same skeleton code to initialize
- the program, create a session, and clean up before exiting:
- </para>
-
-
- <programlisting>
-using System;
-using System.IO;
-using System.Text;
-using System.Threading;
-using org.apache.qpid.client;
-using org.apache.qpid.transport;
-
-...
-
- private static void Main(string[] args)
- {
- string host = args.Length &gt; 0 ? args[0] : "localhost";
- int port = args.Length &gt; 1 ? Convert.ToInt32(args[1]) : 5672;
- Client connection = new Client();
- try
- {
- connection.connect(host, port, "test", "guest", "guest");
- ClientSession session = connection.createSession(50000);
-
- //--------- Main body of program --------------------------------------------
-
- connection.close();
- }
- catch (Exception e)
- {
- Console.WriteLine("Error: \n" + e.StackTrace);
- }
- }
-...
- </programlisting>
- <!--h2-->
- </section>
-
- <section role="h2" id="NETUserGuide-WritingDirectApplications">
- <title>
- Writing
- Direct Applications
- </title>
-
- <para>
- This section describes two programs that implement direct
- messaging using a Direct exchange:
- • org.apache.qpid.example.direct.Producer (from
- example-direct-producer) publishes messages to the amq.direct
- exchange, using the routing key routing_key.
- •org.apache.qpid.example.direct.Listener (from
- example-direct-Listener) uses a message listener to receive
- messages from the queue named message_queue.
- </para>
- <section role="h3" id="NETUserGuide-RunningtheDirectExamples">
- <title>
- Running the
- Direct Examples
- </title>
- <para>
- 1) Make sure your PATH contains the directory
- &lt;home&gt;/qpid/lib
- </para>
- <para>
- 2) Make sure that a qpid broker is running:
- </para>
-
-
- <programlisting>
-$ ps -eaf | grep qpidd
- </programlisting>
-
-
- <para>
- If a broker is running, you should see the qpidd process in the
- output of the above
- command.
- </para>
- <para>
- 3) Read the messages from the message queue using direct
- listener, as follows:
- </para>
-
-
- <programlisting>
-$ cd &lt;home&gt;/qpid/examples/direct
- </programlisting>
-
-
- <para>
- With cygwin:
- </para>
-
-
- <programlisting>
-$ ./example-direct-Listener.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- or with mono:
- </para>
-
-
- <programlisting>
-$ mono ./example-direct-Listener.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- This program is waiting for messages to be published, see next
- step:
- </para>
- <para>
- 4) Publish a series of messages to the amq.direct exchange by
- running direct producer, as follows:
- </para>
-
-
- <programlisting>
-$ cd &lt;home&gt;/qpid/examples/direct
- </programlisting>
-
-
- <para>
- With cygwin:
- </para>
-
-
- <programlisting>
-$ ./example-direct-Producer.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- or with mono:
- </para>
-
-
- <programlisting>
-$ mono ./example-direct-Producer.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- This program has no output; the messages are routed to the
- message queue, as instructed by the binding.
- </para>
- <para>
- 5) Go to the windows where you are running your listener. You
- should see the following output:
- </para>
-
-
- <programlisting>
-Message: Message 0
-Message: Message 1
-Message: Message 2
-Message: Message 3
-Message: Message 4
-Message: Message 5
-Message: Message 6
-Message: Message 7
-Message: Message 8
-Message: Message 9
-Message: That's all, folks!
- </programlisting>
-
-
- <para>
- 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".
- </para>
- <!--h3-->
- </section>
-
- <section role="h3" id="NETUserGuide-ReadingMessagesfromtheQueue">
- <title>
- Reading
- Messages from the Queue
- </title>
-
- <para>
- The program , listener.cs, is a message listener that receives
- messages from a queue.
- </para>
- <para>
- First it creates a queue named message_queue, then binds it to
- the amq.direct exchange using the binding key routing_key.
- </para>
-
-
- <programlisting>
-//--------- Main body of program --------------------------------------------
-// Create a queue named "message_queue", and route all messages whose
-// routing key is "routing_key" to this newly created queue.
-session.queueDeclare("message_queue");
-session.exchangeBind("message_queue", "amq.direct", "routing_key");
- </programlisting>
-
-
- <para>
- The queue created by this program continues to exist after the
- program exits, and any message whose routing key matches the key
- specified in the binding will be routed to the corresponding
- queue by the broker. Note that the queue could have been be
- deleted using the following code:
- </para>
-
-
- <programlisting>
-session.queueDelete("message_queue");
- </programlisting>
-
-
- <para>
- To create a message listener, create a class derived from
- IMessageListener, and override the messageTransfer method,
- providing the code that should be executed when a message is
- received.
- </para>
-
-
- <programlisting>
-public class MessageListener : IMessageListener
-{
- ......
- public void messageTransfer(IMessage m)
- {
- .....
-}
- </programlisting>
-
-
- <para>
- The main body of the program creates a listener for the
- subscription; attaches the listener to a message queue; and
- subscribe to the queue to receive messages from the queue.
- </para>
-
-
- <programlisting>
-lock (session)
-{
- // Create a listener and subscribe it to the queue named "message_queue"
- IMessageListener listener = new MessageListener(session);
- session.attachMessageListener(listener, "message_queue");
- session.messageSubscribe("message_queue");
- // Receive messages until all messages are received
- Monitor.Wait(session);
-}
- </programlisting>
-
-
- <para>
- The MessageListener's messageTransfer() function is called
- whenever a message is received. In this example the message is
- printed and tested to see if it is the final message. Once the
- final message is received, the messages are acknowledged.
- </para>
-
-
- <programlisting>
-BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
-byte[] body = new byte[m.Body.Length - m.Body.Position];
-reader.Read(body, 0, body.Length);
-ASCIIEncoding enc = new ASCIIEncoding();
-string message = enc.GetString(body);
- Console.WriteLine("Message: " + message);
-// Add this message to the list of message to be acknowledged
-_range.add(m.Id);
-if( message.Equals("That's all, folks!") )
-{
- // Acknowledge all the received messages
- _session.messageAccept(_range);
- lock(_session)
- {
- Monitor.Pulse(_session);
- }
-}
- </programlisting>
- <!--h3-->
- </section>
-
- <section role="h3" id="NETUserGuide-PublishingMessagestoaDirectExchange">
- <title>
- Publishing
- Messages to a Direct Exchange
- </title>
- <para>
- The second program in the direct example, Producer.cs, publishes
- messages to the amq.direct exchange using the routing key
- routing_key.
- </para>
- <para>
- First, create a message and set a routing key. The same routing
- key will be used for each message we send, so you only need to
- set this property once.
- </para>
-
-
- <programlisting>
-IMessage message = new Message();
-// The routing key is a message property. We will use the same
-// routing key for each message, so we'll set this property
-// just once. (In most simple cases, there is no need to set
-// other message properties.)
-message.DeliveryProperties.setRoutingKey("routing_key");
- </programlisting>
-
-
- <para>
- Now send some messages:
- </para>
-
-
- <programlisting>
-// Asynchronous transfer sends messages as quickly as
-// possible without waiting for confirmation.
-for (int i = 0; i &lt; 10; i++)
-{
- message.clearData();
- message.appendData(Encoding.UTF8.GetBytes("Message " + i));
- session.messageTransfer("amq.direct", message);
-}
- </programlisting>
-
-
- <para>
- Send a final synchronous message to indicate termination:
- </para>
-
-
- <programlisting>
-// And send a syncrhonous final message to indicate termination.
-message.clearData();
-message.appendData(Encoding.UTF8.GetBytes("That's all, folks!"));
-session.messageTransfer("amq.direct", "routing_key", message);
-session.sync();
- </programlisting>
- <!--h3-->
- </section>
-
- <!--h2-->
- </section>
-
-
- <section role="h2" id="NETUserGuide-WritingFanoutApplications">
- <title>
- Writing
- Fanout Applications
- </title>
-
- <para>
- This section describes two programs that illustrate the use of a
- Fanout exchange.
- </para>
- <itemizedlist>
- <listitem>
- <para>Listener.cs makes a unique queue private for each instance of
- the listener, and binds that queue to the fanout exchange. All
- messages sent to the fanout exchange are delivered to each
- listener's queue.
- </para>
- </listitem>
- <listitem>
- <para>Producer.cs publishes messages to the fanout exchange. It
- does not use a routing key, which is not needed by the fanout
- exchange.
- </para>
- </listitem>
- </itemizedlist>
- <section role="h3" id="NETUserGuide-RunningtheFanoutExamples">
- <title>
- Running the
- Fanout Examples
- </title>
-
- <para>
- 1) Make sure your PATH contains the directory
- &lt;home&gt;/qpid/lib
- </para>
- <para>
- 2) Make sure that a qpid broker is running:
- </para>
-
-
- <programlisting>
-$ ps -eaf | grep qpidd
- </programlisting>
-
-
- <para>
- If a broker is running, you should see the qpidd process in the
- output of the above
- command.
- </para>
- <para>
- 3) In separate windows, start one or more fanout listeners as
- follows:
- </para>
-
-
- <programlisting>
-$ cd &lt;home&gt;/qpid/examples/direct
- </programlisting>
-
-
- <para>
- With cygwin:
- </para>
-
-
- <programlisting>
-$ ./example-fanout-Listener.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- or with mono:
- </para>
-
-
- <programlisting>
-$ mono ./example-fanout-Listener.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- The listener creates a private queue, binds it to the amq.fanout
- exchange, and waits for messages to arrive on the queue. When the
- listener starts, you will see the following message:
- </para>
-
-
- <programlisting>
-Listening
- </programlisting>
-
-
- <para>
- This program is waiting for messages to be published, see next
- step:
- </para>
- <para>
- 4) In a separate window, publish a series of messages to the
- amq.fanout exchange by running fanout producer, as follows:
- </para>
-
-
- <programlisting>
-$ cd &lt;home&gt;/qpid/examples/direct
- </programlisting>
-
-
- <para>
- With cygwin:
- </para>
-
-
- <programlisting>
-$ ./example-fanout-Producer.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- or with mono:
- </para>
-
-
- <programlisting>
-$ mono ./example-fanout-Producer.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- This program has no output; the messages are routed to the
- message queue, as prescribed by the binding.
- </para>
- <para>
- 5) Go to the windows where you are running listeners. You should
- see the following output for each listener:
- </para>
-
-
- <programlisting>
-Message: Message 0
-Message: Message 1
-Message: Message 2
-Message: Message 3
-Message: Message 4
-Message: Message 5
-Message: Message 6
-Message: Message 7
-Message: Message 8
-Message: Message 9
-Message: That's all, folks!
- </programlisting>
-
-
- <para>
- 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".
- </para>
-
- <!--h3-->
- </section>
-
- <!--h2-->
- </section>
-
- <section role="h2" id="NETUserGuide-ConsumingfromaFanoutExchange">
- <title>
- Consuming from a
- Fanout Exchange
- </title>
-
- <para>
- The first program in the fanout example, Listener.cs, creates a
- private queue, binds it to the amq.fanout exchange, and waits for
- messages to arrive on the queue, printing them out as they
- arrive. It uses a Listener that is identical to the one used in
- the direct example:
- </para>
-
-
- <programlisting>
- public class MessageListener : IMessageListener
- {
- private readonly ClientSession _session;
- private readonly RangeSet _range = new RangeSet();
- public MessageListener(ClientSession session)
- {
- _session = session;
- }
-
- public void messageTransfer(IMessage m)
- {
- BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
- byte[] body = new byte[m.Body.Length - m.Body.Position];
- reader.Read(body, 0, body.Length);
- ASCIIEncoding enc = new ASCIIEncoding();
- string message = enc.GetString(body);
- Console.WriteLine("Message: " + message);
- // Add this message to the list of message to be acknowledged
- _range.add(m.Id);
- if (message.Equals("That's all, folks!"))
- {
- // Acknowledge all the received messages
- _session.messageAccept(_range);
- lock (_session)
- {
- Monitor.Pulse(_session);
- }
- }
- }
- }
- </programlisting>
-
-
- <para>
- The listener creates a private queue to receive its messages and
- binds it to the fanout exchange:
- </para>
-
-
- <programlisting>
-string myQueue = session.Name;
-session.queueDeclare(myQueue, Option.EXCLUSIVE, Option.AUTO_DELETE);
-session.exchangeBind(myQueue, "amq.fanout", "my-key");
- </programlisting>
-
-
- <para>
- Now we create a listener and subscribe it to the queue:
- </para>
-
-
- <programlisting>
-lock (session)
-{
- Console.WriteLine("Listening");
- // Create a listener and subscribe it to my queue.
- IMessageListener listener = new MessageListener(session);
- session.attachMessageListener(listener, myQueue);
- session.messageSubscribe(myQueue);
- // Receive messages until all messages are received
- Monitor.Wait(session);
-}
- </programlisting>
-
-
- <section role="h3" id="NETUserGuide-PublishingMessagestotheFanoutExchange">
- <title>
- Publishing
- Messages to the Fanout Exchange
- </title>
-
- <para>
- The second program in this example, Producer.cs, writes messages
- to the fanout queue.
- </para>
-
-
- <programlisting>
-// Unlike topic exchanges and direct exchanges, a fanout
-// exchange need not set a routing key.
-IMessage message = new Message();
-// Asynchronous transfer sends messages as quickly as
-// possible without waiting for confirmation.
-for (int i = 0; i &lt; 10; i++)
-{
- message.clearData();
- message.appendData(Encoding.UTF8.GetBytes("Message " + i));
- session.messageTransfer("amq.fanout", message);
-}
-
-// And send a syncrhonous final message to indicate termination.
-message.clearData();
-message.appendData(Encoding.UTF8.GetBytes("That's all, folks!"));
-session.messageTransfer("amq.fanout", message);
-session.sync();
- </programlisting>
-
- <!--h3-->
- </section>
-
- <!--h2-->
- </section>
-
- <section role="h2" id="NETUserGuide-WritingPublish-2FSubscribeApplications">
- <title>
- Writing
- Publish/Subscribe Applications
- </title>
-
- <para>
- This section describes two programs that implement
- Publish/Subscribe messaging using a topic exchange.
- </para>
- <para>
- • Publisher.cS sends messages to the amq.topic exchange,
- using the multipart routing keys usa.news, usa.weather,
- europe.news, and europe.weather.
- • Listener.cs creates private queues for news, weather,
- usa, and europe, binding them to the amq.topic exchange using
- bindings that match the corresponding parts of the multipart
- routing keys.
- </para>
- <para>
- In this example, the publisher creates messages for topics like
- news, weather, and sports that happen in regions like Europe,
- Asia, or the United States. A given consumer may be interested in
- all weather messages, regardless of region, or it may be
- interested in news and weather for the United States, but
- uninterested in items for other regions. In this example, each
- consumer sets up its own private queues, which receive precisely
- the messages that particular consumer is interested in.
- </para>
- <section role="h3" id="NETUserGuide-RunningthePublishSubscribeExamples">
- <title>
- Running
- the Publish-Subscribe Examples
- </title>
- <para>
- 1) Make sure your PATH contains the directory
- &lt;home&gt;/qpid/lib
- </para>
- <para>
- 2) Make sure that a qpid broker is running:
- </para>
-
-
- <programlisting>
-$ ps -eaf | grep qpidd
- </programlisting>
-
-
- <para>
- If a broker is running, you should see the qpidd process in the
- output of the above
- command.
- </para>
- <para>
- 3) In separate windows, start one or more topic subscribers as
- follows:
- </para>
-
-
- <programlisting>
-$ cd &lt;home&gt;/qpid/examples/direct
- </programlisting>
-
-
- <para>
- With cygwin:
- </para>
-
-
- <programlisting>
-$ ./example-pub-sub--Listener.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- or with mono:
- </para>
-
-
- <programlisting>
-$ mono ./example-pub-sub-Listener.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- You will see output similar to this:
- </para>
-
-
- <programlisting>
-Listening for messages ...
-Declaring queue: usa
-Declaring queue: europe
-Declaring queue: news
-Declaring queue: weather
- </programlisting>
-
-
- <para>
- Each topic consumer creates a set of private queues, and binds
- each queue to the amq.topic exchange together with a binding that
- indicates which messages should be routed to the queue.
- </para>
- <para>
- 4) In another window, start the topic publisher, which publishes
- messages to the amq.topic exchange, as follows:
- </para>
-
-
- <programlisting>
-$ cd &lt;home&gt;/qpid/examples/direct
- </programlisting>
-
-
- <para>
- With cygwin:
- </para>
-
-
- <programlisting>
-$ ./example-pub-sub-Producer.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- or with mono:
- </para>
-
-
- <programlisting>
-$ mono ./example-pub-sub-Producer.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- This program has no output; the messages are routed to the
- message queues for each topic_consumer as specified by the
- bindings the consumer created.
- </para>
- <para>
- 5) Go back to the window for each topic consumer. You should see
- output like this:
- </para>
-
-
- <programlisting>
-Message: Message 0 from usa
-Message: Message 0 from news
-Message: Message 0 from weather
-Message: Message 1 from usa
-Message: Message 1 from news
-Message: Message 2 from usa
-Message: Message 2 from news
-Message: Message 3 from usa
-Message: Message 3 from news
-Message: Message 4 from usa
-Message: Message 4 from news
-Message: Message 5 from usa
-Message: Message 5 from news
-Message: Message 6 from usa
-Message: Message 6 from news
-Message: Message 7 from usa
-Message: Message 7 from news
-Message: Message 8 from usa
-Message: Message 8 from news
-Message: Message 9 from usa
-....
-Message: That's all, folks! from weather
-Shutting down listener for control
-Message: That's all, folks! from europe
-Shutting down listener for control
- </programlisting>
-
-
- <para>
- 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".
- </para>
- <!--h3-->
- </section>
-
-
- <section role="h3" id="NETUserGuide-PublishingMessagestoaTopicExchange">
- <title>
- Publishing
- Messages to a Topic Exchange
- </title>
-
- <para>
- The first program in the publish/subscribe example, Publisher.cs,
- defines two new functions: one that publishes messages to the
- topic exchange, and one that indicates that no more messages are
- coming.
- </para>
- <para>
- The publishMessages function publishes a series of five messages
- using the specified routing key.
- </para>
-
-
- <programlisting>
-private static void publishMessages(ClientSession session, string routing_key)
-{
- IMessage message = new Message();
- // Asynchronous transfer sends messages as quickly as
- // possible without waiting for confirmation.
- for (int i = 0; i &lt; 10; i++)
- {
- message.clearData();
- message.appendData(Encoding.UTF8.GetBytes("Message " + i));
- session.messageTransfer("amq.topic", routing_key, message);
- }
-}
- </programlisting>
-
-
- <para>
- The noMoreMessages function signals the end of messages using the
- control routing key, which is reserved for control messages.
- </para>
-
-
- <programlisting>
-private static void noMoreMessages(ClientSession session)
-{
- IMessage message = new Message();
- // And send a syncrhonous final message to indicate termination.
- message.clearData();
- message.appendData(Encoding.UTF8.GetBytes("That's all, folks!"));
- session.messageTransfer("amq.topic", "control", message);
- session.sync();
-}
- </programlisting>
-
-
- <para>
- In the main body of the program, messages are published using
- four different routing keys, and then the end of messages is
- indicated by a message sent to a separate routing key.
- </para>
-
-
- <programlisting>
-publishMessages(session, "usa.news");
-publishMessages(session, "usa.weather");
-publishMessages(session, "europe.news");
-publishMessages(session, "europe.weather");
-
-noMoreMessages(session);
- </programlisting>
- <!--h3-->
- </section>
-
- <section role="h3" id="NETUserGuide-ReadingMessagesfromtheQueue2">
- <title>
- Reading
- Messages from the Queue
- </title>
-
- <para>
- The second program in the publish/subscribe example, Listener.cs,
- creates a local private queue, with a unique name, for each of
- the four binding keys it specifies: usa.#, europe.#, #.news, and
- #.weather, and creates a listener.
- </para>
-
-
- <programlisting>
-Console.WriteLine("Listening for messages ...");
-// Create a listener
-prepareQueue("usa", "usa.#", session);
-prepareQueue("europe", "europe.#", session);
-prepareQueue("news", "#.news", session);
-prepareQueue("weather", "#.weather", session);
- </programlisting>
-
-
- <para>
- The prepareQueue() method creates a queue using a queue name and
- a routing key supplied as arguments it then attaches a listener
- with the session for the created queue and subscribe for this
- receiving messages from the queue:
- </para>
-
-
- <programlisting>
-// 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);
- </programlisting>
- <!--h3-->
- </section>
- <!--h2-->
- </section>
-
- <section role="h2" id="NETUserGuide-WritingRequest-2FResponseApplications">
- <title>
- Writing
- Request/Response Applications
- </title>
-
- <para>
- 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.
- </para>
- <itemizedlist>
- <listitem>
- <para>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.
- </para>
- </listitem>
- </itemizedlist>
- <section role="h3" id="NETUserGuide-RunningtheRequest-2FResponseExamples">
- <title>
- Running
- the Request/Response Examples
- </title>
- <para>
- 1) Make sure your PATH contains the directory
- &lt;home&gt;/qpid/lib
- </para>
- <para>
- 2) Make sure that a qpid broker is running:
- </para>
-
-
- <programlisting>
-$ ps -eaf | grep qpidd
- </programlisting>
-
-
- <para>
- If a broker is running, you should see the qpidd process in the
- output of the above
- command.
- </para>
- <para>
- 3) Run the server.
- </para>
- <para>
- $ cd &lt;home&gt;/qpid/examples/direct
- </para>
-
-
- <programlisting>
- With cygwin:
- </programlisting>
-
-
- <para>
- $ ./example-request-response-Server.exe [hostname] [portnumber]
- </para>
-
-
- <programlisting>
- or with mono:
- </programlisting>
-
-
- <para>
- $ mono ./example-request-response-Server.exe [hostname] [portnumber]
- </para>
-
-
- <programlisting>
- You will see output similar to this:
- </programlisting>
-
-
- <para>
- Waiting for requests
- </para>
-
-
- <programlisting>
-4) In a separate window, start a client:
-
-$ cd &lt;home&gt;/qpid/examples/direct
- </programlisting>
-
-
- <para>
- With cygwin:
- </para>
-
-
- <programlisting>
-$ ./example-request-response-Client.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- or with mono:
- </para>
-
-
- <programlisting>
-$ mono ./example-request-response-Client.exe [hostname] [portnumber]
- </programlisting>
-
-
- <para>
- You will see output similar to this:
- </para>
-
-
- <programlisting>
-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!
- </programlisting>
-
-
- <para>
- 4) Go back to the server window, the output should be similar to
- this:
- </para>
-
-
- <programlisting>
-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!
- </programlisting>
-
-
- <para>
- 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".
- </para>
- <!--h3-->
- </section>
-
-
- <section role="h3" id="NETUserGuide-TheClientApplication">
- <title>
- The Client
- Application
- </title>
-
- <para>
- 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.
- </para>
-
-
- <programlisting>
-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);
- </programlisting>
-
-
- <para>
- 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.
- </para>
-
-
- <programlisting>
-IMessage request = new Message();
-request.DeliveryProperties.setRoutingKey("request");
-request.MessageProperties.setReplyTo(new ReplyTo("amq.direct", response_queue));
- </programlisting>
-
-
- <para>
- Now send some requests...
- </para>
-
-
- <programlisting>
-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);
-}
- </programlisting>
-
-
- <para>
- And wait for responses to arrive:
- </para>
-
-
- <programlisting>
-Console.WriteLine("Waiting for all responses to arrive ...");
-Monitor.Wait(session);
- </programlisting>
- <!--h3-->
- </section>
-
- <section role="h3" id="NETUserGuide-TheServerApplication">
- <title>
- The Server
- Application
- </title>
-
- <para>
- The second program in the request-response example, Server.cs,
- uses the reply-to property as the routing key for responses.
- </para>
- <para>
- The main body of Server.cs creates an exclusive queue for
- requests, then waits for messages to arrive.
- </para>
-
-
- <programlisting>
-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);
-}
- </programlisting>
-
-
- <para>
- 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.
- </para>
-
-
- <programlisting>
-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);
- </programlisting>
-
- <!--h3-->
- </section>
- <!--h2-->
- </section>
- <!--h1-->
- </section>
-
-
- </section>