CloudAMQP with Ruby Getting started

Client libraries Many options

Ruby developers has a number of options for AMQP client libraries:

  • AMQP::Client for Ruby is a small, fast and safe AMQP library for Ruby written by CloudAMQP and offers plenty of modern adaptations and supports all maintained Ruby versions. It is measured to be 4 times faster than other Ruby clients
  • Bunny is a well used and popular client
  • March Hare is an idiomatic, fast and well-maintained (J)Ruby DSL on top of the RabbitMQ Java client
  • AMQP EventMachine-based RabbitMQ client is deprecated. Only use if you are already using EventMachine

Get started with Ruby and AMQP::Client

Usage

The client has two APIs. A low level API that matches the AMQP protocol very well, it can do everything the protocol allows, but requires some knowledge about the protocol, and doesn't handle reconnects. And, a high-level API that is a bit easier to get started with, and also handles reconnection automatically.

Low level API

require "amqp-client"
# Opens and establishes a connection
conn = AMQP::Client.new("amqp://guest:guest@localhost").connect

# Open a channel
ch = conn.channel

# Create a temporary queue
q = ch.queue_declare

# Publish a message to said queue
ch.basic_publish_confirm "Hello World!", "", q.queue_name, persistent: true

# Poll the queue for a message
msg = ch.basic_get(q.queue_name)

# Print the message's body to STDOUT
puts msg.body

High level API

# Start the client, it will connect and once connected it will reconnect if that connection is lost
# Operation pending when the connection is lost will raise an exception (not timeout)
amqp = AMQP::Client.new("amqp://localhost").start

# Declares a durable queue
myqueue = amqp.queue("myqueue")

# Bind the queue to any exchange, with any binding key
myqueue.bind("amq.topic", "my.events.*")

# The message will be reprocessed if the client loses connection to the broker
# between message arrival and when the message was supposed to be ack'ed.
myqueue.subscribe(prefetch: 20) do |msg|
  process(JSON.parse(msg.body))
  msg.ack
rescue
  msg.reject(requeue: false)
end

# Publish directly to the queue
myqueue.publish({ foo: "bar" }.to_json, content_type: "application/json")

# Publish to any exchange
amqp.publish("my message", "amq.topic", "topic.foo", headers: { foo: 'bar' })
amqp.publish(Zlib.gzip("an event"), "amq.topic", "my.event", content_encoding: 'gzip')

Installation

Get started with amqp-client by adding this line to your application's Gemfile:

gem 'amqp-client'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install amqp-client

GitHub repository

Code example using Bunny

The following example will use the synchronous client Bunny to publish a message and to consume it.

We begin by adding the environment variable CLOUDAMQP_URL to our .env file. You can find your CloudAMQP URL under Details in the CloudAMQP Console.

➜ vim .env
CLOUDAMQP_URL="amqps://user:password@host/user"
~

Then, we add these gems to our Gemfile if they are not yet added.

➜ vim Gemfile
source 'https://rubygems.org'
ruby '2.7.0'
gem 'bunny'
gem 'dotenv'
~

Further, we create a script and name it publish.rb. In the publish.rb script we will write down a simple example on how to publish a message.

require "bunny"
require "dotenv/load"

connection = Bunny.new ENV['CLOUDAMQP_URL']
connection.start # Start a connection with the CloudAMQP server
channel = connection.create_channel # Declare a channel
queue = channel.queue("bunny_queue") # Declare a queue

# Declare a default direct exchange which is bound to all queues
exchange = channel.exchange("")

# Publish a message to the exchange which then gets routed to the queue
exchange.publish("Hello everybody!", :key => queue.name)

connection.close # Finally, close the connection

Then, we create another script and name it subscribe.rb. In the subscribe.rb script we will write down a simple example on how to consume a message.

require "bunny"
require 'dotenv/load'

connection = Bunny.new ENV['CLOUDAMQP_URL']
connection.start  # Start a connection with the CloudAMQP server
channel = connection.create_channel # Declare a channel
queue = channel.queue("bunny_queue") # Declare a queue

begin # Consume messages
  puts ' [*] Waiting for messages. To exit press CTRL+C'
  queue.subscribe(block: true) do |_delivery_info, _properties, body|
    puts " [x] Consumed message: []"
  end
rescue Interrupt => _
  connection.close # Close the connection
  exit(0)
end

Finally, in each terminal window, we run the scripts subscribe.rb and publish.rb respectively.

➜ ruby publish.rb
➜
➜ ruby subscribe.rb
> [*] Waiting for messages. To exit press CTRL+C
> [x] Consumed message: Hello everybody!

For more information on Bunny, visit rubybunny.info

Code example using March Hare

The following example will use March Hare to publish a message and to consume it. Make sure that you have JRuby 9.x installed. It can be installed with the following command

➜ rvm install jruby

Lets start by adding the environment variable CLOUDAMQP_URL to our .env file. You can find your CloudAMQP URL under Details in the CloudAMQP Console.

➜ vim .env
CLOUDAMQP_URL="amqps://user:password@host/user"
~

Then, we add these gems to our Gemfile if they are not yet added.

➜ vim Gemfile
source 'https://rubygems.org'
ruby '2.7.0'
gem 'march_hare'
gem 'dotenv'
~

Further, we create a script and name it publish.rb. In the publish.rb script we will write down a simple example on how to publish a message.

require "march_hare"
require "dotenv/load"

connection = MarchHare.connect(:uri => ENV['CLOUDAMQP_URL'])
channel = connection.create_channel  # Declare a channel
queue  = channel.queue("hare_queue") # Declare a queue

# Declare a default direct exchange which is bound to all queues
exchange = channel.default_exchange

# Publish a message to the exchange which then gets routed to the queue
exchange.publish("Hello Hare!", :routing_key => queue.name)

# Finally, close the connection
connection.close

Then, we create another script and name it subscribe.rb. In the subscribe.rb script we will write down a simple example on how to consume a message.

require "march_hare"
require "dotenv/load"

connection = MarchHare.connect(:uri => ENV['CLOUDAMQP_URL'])
channel = connection.create_channel  # Declare a channel
queue  = channel.queue("hare_queue") # Declare a queue

#Consume messages
begin
    puts ' [*] Waiting for messages. To exit press CTRL+C'
    consume  = queue.subscribe do |metadata, payload|
    puts " [x] Consumed message: payload"
  end
rescue Interrupt => _
    connection.close
    exit(0)
  end

Finally, in each terminal window, we run the scripts subscribe.rb and publish.rb respectively.

➜ ruby publish.rb
➜
➜ ruby subscribe.rb
> [*] Waiting for messages. To exit press CTRL+C
> [x] Consumed message: Hello Hare!

For more information on March Hare, visit rubymarchhare.info

Code example using Sneakers

The following example will use sneakers to consume a message from RabbitMQ

#sneakers_app.rb

require 'sneakers' # don't forget to put gem "sneakers" in your Gemfile
require 'sneakers/runner'

class Processor
  include Sneakers::Worker
  from_queue :default_queue
  def work(msg)
    puts "Msg received: " + msg
  end
end

opts = {
  :amqp => 'CLOUDAMQP_URL', # Replace the string with your AMQP url that you can find on CloudAMQP console page
  :vhost => 'username', # Replace with the vhost/username that you can find on CloudAMQP console page
  :exchange => 'sneakers',
  :exchange_type => :direct
}

Sneakers.configure(opts)
r = Sneakers::Runner.new([Processor])
r.run

Run your application:

$ ruby sneakers_app.rb

If you go to your RabbitMQ admin console -> queues, you will see that a new queue named default_queue is created. Push a couple of messages by entering a text into the payload under Publish message, and press Publish message. You should now see some output in your terminal, telling you that the message is received and that it is ready to be handled.

Code example Build realtime apps!

Here's another example which uses the evented AMQP library, in combination with Sinatra and Server Sent Events. It shows how to build a simple real time application, using CloudAMQP as the backbone.

The application can also be seen live at amqp-sse.herokuapp.com.

Video

Here's a video recording showing how to setup a CloudAMQP instance and connect to it using Ruby and the Bunny library:

Further reading