3.6.3. "Hello World" Walk-through
The Qpid Messaging client development libraries contain the functions we need to communicate with the messaging broker and create and manage messages, so our first task is to import them to our program:
- Python
from qpid.messaging import *
- C++
#include <qpid/messaging/Connection.h> #include <qpid/messaging/Message.h> #include <qpid/messaging/Receiver.h> #include <qpid/messaging/Sender.h> #include <qpid/messaging/Session.h> using namespace qpid::messaging;
- C#/.NET
using Org.Apache.Qpid.Messaging; namespace Org.Apache.Qpid.Messaging {
To communicate with a message broker we need a connection. We get one by creating an instance of a
Connection
object. The Connection object constructor takes the url of the broker as its parameter:
- Python
connection = Connection("localhost:5672")
- C++
Connection connection(broker);
- C#/.NET
Connection connection = null; connection = new Connection(broker);
When you connect to a remote server that requires authentication you can provide a connection url in the form
username/password@serverurl:port
. If you try this with a remote server, remember to open the firewall on the message broker to allow incoming connections for the broker port.
To open a connection using the AMQP 1.0 protocol, specify it like this:
- C++
Connection connection(broker, "{protocol:amqp1.0}");
- C#/.NET
connection = new Connection(broker, "{protocol:amqp1.0}");
Now that we have a Connection instance configured for our broker, the next step is to open the connection. The Connection object has an
open
method, which opens a configured connection.
Opening the connection might fail, if, for example, the message broker is off-line, so for languages that support it we will wrap it in a try:except block, and catch any exception.
Remember that Python uses indentation, so be careful with your spacing:
- Python
try: connection.open()
- C++
try { connection.open();
- C#/.NET
connection.Open();
Now that we have an open connection to the server, we need to create a session. A session is a scoped conversation between our application and the server. The server uses the scope of the session to enforce exclusive access and session-scoped lifetimes of queues.
The
Connection
object has a createSession
method (session
in Python) that returns a Session
object, so we get a session from the connection that we created previously:
- Python
session = connection.session()
- C++
Session session = connection.createSession();
- C#/.NET
Session session = connection.CreateSession();
The
Session
object has sender
and receiver
methods, which take a target or source address as a parameter, and return a Sender
and a Receiver
object, respectively. These are the objects that we need to send and receive messages, so we will create them by calling the respective methods of our session. We will use the amq.topic
exchange for this demo. This is a pre-configured exchange on the broker, so we don't need to create it, and we can rely on its presence:
- Python
sender = session.sender("amq.topic") receiver = session.receiver("amq.topic")
- C++
Receiver receiver = session.createReceiver(address); Sender sender = session.createSender(address);
- C#/.NET
Receiver receiver = session.CreateReceiver(address); Sender sender = session.CreateSender(address);
A sender can be thought of as a router. It routes messages from our application to the broker. The parameter we pass to the sender's constructor is the destination on the broker that our messages will be routed to. In this case, our sender will route messages to the
amq.topic
exchange on the broker. Because our routing target is an exchange, it will be routed further from there by the broker.
A receiver can be thought of as a subscriber. When we create a receiver, the parameter we pass to the constructor is resolved to an object on the server. If the object is a queue, then our receiver is subscribed to that queue. If the object is an exchange, as it is in this case, then a queue is created in the background and subscribed to the exchange for us. We will look in more detail at this later. For now, suffice it to say that our sender will send a message to the
amq.topic
exchange, and our receiver will receive it in a queue.
Now that we have a sender and a receiver, it's time to create a message to send. The
Message
object takes as a parameter to its constructor a string that becomes the message.content
:
- Python
message = Message("Hello World!")
The
Message
object constructor sets the correct content-type
when you set the message.content
through the constructor. However, if you set it after creating the Message
object by assigning a value to the message.content
property, then you also need to set the message.content_type
property appropriately.
We can now use the
send
method of our sender to send the message to the broker:
- Python
sender.send(message)
- C++
sender.send(Message("Hello world!"));
- C#/.NET
sender.Send(new Message("Hello world!"));
The message is sent to the
amq.topic
exchange on the message broker.
When we created our receiver, in the background the broker created a private temporary queue and subscribed it to the
amq.topic
exchange for us. The message is now waiting in that queue.
The next step is to retrieve the message from the broker using the
fetch
method of our receiver:
- Python
fetchedmessage = receiver.fetch(timeout=1)
- C++
Message message = receiver.fetch(Duration::SECOND * 1);
- C#/.NET
Message message = new Message(); message = receiver.Fetch(DurationConstants.SECOND * 1);
The
timeout
parameter tells fetch
how long to wait for a message. If we do not set a timeout the receiver will wait indefinitely for a message to appear on the queue. If we set the timeout to 0, the receiver will check the queue and return immediately if nothing is there. We set it to timeout in 1 second to ensure ample time for our message to be routed and appear in the queue.
We should now have a message, so we will print it out.
Fetch
returns a Message
object, so we will print its content
property:
- Python
print fetchedmessage.content
- C++
std::cout << message.getContent() << std::endl;
- C#/.NET
Console.WriteLine("{0}", message.GetContent());
To finish the transaction, acknowledge receipt of the message, which allows the message broker to clear it from the queue (dequeue the message):
- Python
session.acknowledge()
- C++
session.acknowledge();
- C#/.NET
session.Acknowledge();
And finally, catch any exceptions for languages that support exception handling, and print something sensible to the console if they occur, and close our connection to the message broker:
- Python
except MessagingError,m: print m connection.close()
- C++
} catch(const std::exception& error) { std::cerr << error.what() << std::endl; connection.close(); return 1; }
- C#/.NET
} catch (Exception e) { Console.WriteLine("Exception {0}.", e); if (connection != null) connection.Close(); }
To run the program, save the file as
helloworld.py
, and then run it using the command python helloworld.py
. If the message broker is running on your local machine, you should see the words: "Hello World!" printed on your programlisting.