| = Qpid Proton AMQP Library |
| |
| This is a library for sending and receiving AMQP messages. It can be used to |
| build clients and servers. |
| |
| == Installing |
| |
| You can install the latest published Gem with |
| |
| gem install qpid_proton |
| |
| *NOTE:* before installing the Gem, you must install the proton-C library. |
| |
| The proton-C library can be installed by the package manager on many platforms, |
| e.g. yum install qpid-proton-c # Fedora < 25, RHEL < 7 dnf install |
| qpid-proton-c # Fedora >= 25, RHEL >= 7 |
| |
| You can also download a source release or the latest development code from |
| http://qpid.apache.org/proton. To build from source: |
| |
| cmake -DBUILD_BINDINGS=ruby && make |
| |
| This produces a Gem file at: |
| |
| BUILD_DIR/ruby/qpid_proton-VERSION.gem |
| |
| You can install the gem with +gem install+ |
| |
| == Overview |
| |
| {Qpid::Proton::Message} represents a message that can be sent or received. A |
| message body can be a string or byte sequence encoded any way you |
| choose. However, AMQP also provides standard, interoperable encodings for basic |
| data types like {Hash} and {Array}. The equivalent AMQP encodings can be |
| understood as maps or sequences in any programming langauge with an AMQP |
| library. |
| |
| {Qpid::Proton::Link} allows messages to be transferred to or from a remote AMQP |
| process. The {Qpid::Proton::Sender} subclass sends messages, the |
| {Qpid::Proton::Receiver} subclass receives them. Links have a source and target |
| address, as explained below. |
| |
| Links are grouped in a {Qpid::Proton::Session}. Messages in the same session are |
| sent sequentially, while those on different sessions can be interleaved. A large |
| message being sent on one session does not block messages being sent on another |
| session. |
| |
| Sessions belong to a {Qpid::Proton::Connection}. If you don't need multiple |
| sessions, a connection will create links directly using a default session. |
| |
| A {Qpid::Proton::Transfer} represents the transfer of a message, the |
| {Qpid::Proton::Delivery} subclass allows a receiver to accept or reject an |
| incoming message. The {Qpid::Proton::Tracker} subclass allows a sender to track |
| the status of a sent message and find out if it was accepted or rejected. |
| |
| A transfer is _settled_ when both ends are done with it. Different settlement |
| methods give different levels of reliability: at-most-once, at-least-once, and |
| exactly-once. See below. |
| |
| == Anatomy of a Proton application |
| |
| {Qpid::Proton::Container} is the top-level object in a Proton application. A |
| client uses {Qpid::Proton::Container#connect} to establish connections. A server |
| uses {Qpid::Proton::Container#listen} to accept connections. |
| |
| Proton is an event-driven library. You implement one or more _handlers_ which |
| subclass {Qpid::Proton::MessagingHandler MessagingHandler} and override |
| functions to handle AMQP events, such as {Qpid::Proton::MessagingHandler#on_message |
| #on_message}. Each connection is associated with a handler for its |
| events. {Qpid::Proton::Container#run} polls all connections and listeners and |
| calls the event handling functions on your handlers. |
| |
| A multi-threaded application can call {Qpid::Proton::Container#run} in more than |
| one thread, the container will use all the {Qpid::Proton::Container#run #run} |
| threads as a thread pool to dispatch events. |
| |
| == Sources and targets |
| |
| Every link has two addresses, _source_ and _target_. The most common pattern for |
| using these addresses is as follows: |
| |
| When a client creates a {Qpid::Proton::Receiver Receiver} link, it sets the |
| _source_ address. This means "I want to receive messages from this source". This |
| is often referred to as "subscribing" to the source. When a client creates a |
| {Qpid::Proton::Sender Sender} link, it sets the _target_ address. This means "I |
| want to send to this target". |
| |
| In the case of a broker, the source or target usually refers to a queue or |
| topic. In general they can refer to any AMQP-capable node. |
| |
| In the request-response pattern, a request message carries a reply-to address |
| for the response message. This can be any AMQP address, but it is often useful |
| to create a temporary address for the response message. The client creates a |
| receiver with no source address and the dynamic flag set. The server generates a |
| unique source address for the receiver, which is discarded when the link |
| closes. The client uses this source address as the reply-to when it sends the |
| request, so the response is delivered to the client's receiver. |
| |
| The server_direct.cpp example shows how to implement a request-response server. |
| |
| == Settling a Message Transfer |
| |
| A message transfer is _settled_ at one end of a link when that end of the link |
| has finished with the message and forgotten it. |
| |
| _Pre-settled_ messages are settled by the sender before sending. This gives _at |
| most once_ reliability(also known as _best effort_, _unreliable_ or _fire and |
| forget_) since the sender never knows for sure if the message arrived. If the |
| connection is lost before the message is received by the receiver, the message |
| will not be delivered. |
| |
| If the sender does not pre-settle a message, then the receiver settles it once |
| it has been processed. The sender is informed of the settlement via the |
| {Qpid::Proton::Tracker Tracker}. If the connection is lost before the sender has |
| received notice of settlement, the delivery is considered in-doubt and the |
| sender can re-send it. This ensures it eventually gets delivered (provided the |
| connection and link can be reestablished) but it is possible for multiple copies |
| of the same message are delivered, so the receiver must be aware of that. This |
| is known as _at_least_once_ reliability. |
| |
| == Multi-threaded applications |
| |
| {Qpid::Proton::Container#run} can be called by multiple threads concurrently, |
| giving the container a thread-pool to execute handler methods in parallel. |
| |
| Instances of {Qpid::Proton::Connection} and objects associated with it |
| ({Qpid::Proton::Session}, {Qpid::Proton::Sender}, {Qpid::Proton::Receiver}, |
| {Qpid::Proton::Delivery}, {Qpid::Proton::Tracker}) are not thread-safe and must |
| be used correctly when multiple threads call {Qpid::Proton::Container#run} |
| |
| Calls to {Qpid::Proton::MessagingHandler} and {Qpid::Proton::Listener::Handler} |
| methods by the {Qpid::Proton::Container} are automatically serialized for each |
| connection instance. |
| |
| Other threads may have code similarly serialized by adding it to the |
| {Qpid::Proton::Connection#work_queue} for the connection. Each object related |
| to a {Qpid::Proton::Connection} also provides a +work_queue+ method. |
| |
| You also need to use the {Qpid::Proton::WorkQueue} to communicate between a |
| {Qpid::Proton::MessagingHandler} method call for one connection instance, and a |
| different {Qpid::Proton::Connection} instance in the same container, as separate |
| connections can be processed in parallel. |