Simple Examples
The Broker
The examples come with a sample broker which can be used by other examples and which also works as an example itself. For now we'll just start up the broker example and tell it to listen on port 8888:
$ ruby broker.rb amqp://:8888
Listening on amqp://:8888
This example broker will receive messages, create queues as needed, and deliver messages to endpoints.
Hello World Using A Broker
Our first example creates an endpoint that sends messages to a queue to which it is subscribed. So it both sends and receives a message.
To start it, simply run:
$ ruby helloworld.rb //:8888
Hello world!
As you can see, the classic message was output by the example. Now let's take a look at what's going on under the covers.
Events When Talking To A Broker
The following events occur while helloworld.rb runs:
- on_start - Fired when the application is started.
- on_sendable - Fired when a message can be sent.
- on_message - Fired when a message is received.
More Complex Examples
Now that we've covered the basics with the archetypical hello world app, let's look at some more interesting examples.
The following two client examples send and receive messages to an external broker or server:
- simple_send.rb - connect to a server, send messages to an address
- simple_recv.rb - connect to a server, receives messages from an address
For example: start broker.rb
; run simple_send.rb
to send messages to a
broker queue; then simple_recv.rb
to receive the messages from the broker.
The following two examples are servers that can be connected to directly, without a broker:
- direct_send.rb - sends messages directly to a receiver and listens for responses itself, and
- direct_recv.rb - receives messages directly.
For example if you start direct_recv.rb
, you can connect to it directly with
simple_send.rb
vice-versa with direct_send.rb
and simple_recv.rb
In this set of examples we see the following event occurring, in addition to what we've seen before:
- on_transport_close - Fired when the network transport is closed.
Now About That Broker example
The broker.rb example application is a nice demonstration of doing something more interesting in Ruby with Proton, and shows how to use multiple threads.
The broker listens for incoming connections and sender/receiver links. It uses the source and target address of senders and receivers to identify a queue. Messages from receivers go on the queue, and are sent via senders.
The components of the broker example include:
- Broker is a Listener::Handler that accepts connections, and manages the set of named queues.
- BrokerHandler extends MessagingHandler to accept incoming connections, senders and receivers and transfers messages between them and the Broker's queues.
- MessageQueue - A queue of messages that keeps track of waiting senders.
The broker application demonstrates a new set of events:
- on_sender_open - Fired when a sender link is opened, the broker gets the address and starts sending messages from the corresponding queue.
- on_sender_close - Fired when a sender link is closed, remove the sender from the queue so no more messages are sent.
- on_connection_close - Fired when the remote connection is closes, close all senders.
- on_transport_close - Fired when the transport (socket) has closed, close all senders.
It also demonstrates aspects of multi-threaded proton:
-
Thread safe MessageQueue Uses a Mutex to make actions atomic when called concurrently.
-
Using WorkQueue Proton objects like Sender are not thread safe. They are
normally only used in MessagingHandler#on_ callbacks. To request work from a
different thread you can add a code block to a WorkQueue, as shown in
MessageQueue#push.
-
Listener::Handler The broker creates a new BrokerHandler instance for
each accepted connection. The container ensures that calls on each handler instance
are serialized even if there are multiple threads in the container.
-
Calling Container#run in multiple threads The Container uses threads that call
#run as a thread pool to dispatch calls to MessagingHandler instances. Even
if there are multiple threads, calls to handler instance are serialized.