Jul 28

Publish\Subscribe Messaging with Flex and Rails using Apache ActiveMQ, ActiveMessaging, and STOMP

Tag: AS3, ActiveMQ, ActiveMessaging, Flex and Rails, Messaging, STOMP, Server PushDerek Wischusen @ 6:09 pm

This will be the first in a series of posts where I’ll cover how you can do publish\subscribe and other messaging methods with Flex and Rails using ActiveMQ, the Rails ActiveMessaging plugin, and the STOMP protocol to get them all communicating. In this post I will describe how to create a simple Flex consumer that receives messages from a Rails app that serves as the producer.

Before we get to that, let’s start with a brief description of the technologies involved. The following descriptions are from the technologies’ respective websites:

Apache ActiveMQ

Apache ActiveMQ is the most popular and powerful open source Message Broker.

Apache ActiveMQ is fast, supports many Cross Language Clients and Protocols and many advanced features while fully supporting JMS 1.1 and J2EE 1.4. Apache ActiveMQ is released under the Apache 2.0 License.

ActiveMessaging

ActiveMessaging is an attempt to bring the simplicity and elegance of rails development to the world of messaging. Messaging, (or event-driven architecture) is widely used for enterprise integration, with frameworks such as Java’s JMS, and products such as ActiveMQ, Tibco, IBM MQSeries, etc.

And, lastly the protocol that we’re going to use to tie everything together:

STOMP

The Stomp project is the Streaming Text Orientated Messaging Protocol site (or the Protocol Briefly Known as TTMP and Represented by the symbol :ttmp).

Stomp provides an interoperable wire format so that any of the available Stomp Clients can communicate with any Stomp Message Broker to provide easy and widespread messaging interop among languages, platforms and brokers.

Now that you know a little something about technologies that we will be using (I am assuming that you probably already know about Flex and Rails), let’s build something.

Prerequisites:

  • Ruby 1.8.6
  • Rails 1.2.3
  • Java 1.5.0_07+
  • MySQL (or any other database that works with Rails migrations)

Here are the source files if you would like to follow along.

Source Files:

Creating the Rails App

Let’s kick things off by creating the Rails producer app. It’s going to be a really small app called sales_report that is used to capture and distribute simple sales data.

1. Crack open the database of your choice and create a database called sales_report. For example,

$ CREATE DATABASE sales_report

2. Create the app

$ rails sales_report
$ cd sales_report

3. Generate your sale model

$ script/generate model sale

4. Open up the 001_create_sales.rb migration that you just created in db/migrate and add the following

  def self.up
    create_table :sales do |t|
      t.column :customer, :string
      t.column :product, :string
      t.column :quantity, :integer
    end
  end

5. Open up config/database.yml and configure it for your database. For example,

development:
    adapter: mysql
    database: sales_report
    username: root
    password: your_password_here
    socket: /tmp/mysql.sock

6. Run the migration rake task to create the sale table that you defined in migration file above.

$ rake db:migrate

7. Generate the sales controller.

$ script/generate controller sales index

8. For this application,we really just need to be able to produce new sales records, so Rails scaffolding will work just fine. Open up sales_controller.rb and make it look like this:

class SalesController < ApplicationController
  scaffold :sale
end

9. That’s all for the basic Rails app. Now it’s time to start working with ActiveMessaging. So, let’s install the plugin and a couple of gems that it uses.

$ gem install daemons
$ gem install stomp
$ script/plugin install http://activemessaging.googlecode.com/svn/trunk/plugins/activemessaging

10. Now that we have everything installed, let’s create an ActiveMessaging processor. We don’t actually need the processor for this tutorial, but it generates some other files that we do need.

$ script/generate processor sale
create  app/processors
create  app/processors/sale_processor.rb
create  test/functional/sale_processor_test.rb
create  config/messaging.rb
create  config/broker.yml
create  app/processors/application.rb
create  script/poller

11. Open up config/broker.yml and configure the stomp adapter as follows:

development:
   adapter:
   stomplogin: ""
   passcode: ""
   host: localhost
   port: 61613
   reliable: false

12. Now open up config/messaging.rb and specify the destination for the queue, like so

ActiveMessaging::Gateway.define do |s|
  s.destination :sale_queue, '/queue/Sale'
end

13. Almost done. The last step for the Rails app is to create an Observer that watches the Sale model to see when a new sale is saved to the database and then publishes it to the queue that you just set up.

$ script/generate observer sale

14. Now edit app/model/sale_observer.rb as follows.

require 'activemessaging/processor'
class SaleObserver < ActiveRecord::Observer
  include ActiveMessaging::MessageSender
  publishes_to :sale_queue
 
  def after_save(sale)
    record = sale.to_xml
    publish :sale_queue, record
  end
end

This class watches the Sale model. When a new sale record is saved to the database the after_save method is called. This method takes the new sale ActiveRecord instance converts it to XML and publishes it to the sale_queue.

15. Finally, boot up the server.

$ script/server

Installing ActiveMQ
Installing and running ActiveMQ is dead simple.

1. Just go and grab one of the latest snapshots from here.

2. Download it and unzip it.

3. Navigate to activemq/bin and run activemq.

4. If you need additional instruction, check out this page.

5. Once you have ActiveMQ up and running, proceed to the next section on building the Flex app.

The Flex App and the STOMP AS3 Client
To get Flex talking with ActiveMQ we are going to be using the STOMP protocol. When I first started looking into ActiveMQ I came across this ActionScript 3 STOMP client developed by Richard Jewson. I’ve since update the library substantially so that it implements the majority of the STOMP protocol. For now, you can get the source for the STOMP library by downloading the source for the Flex app. I am going to submitting this code to the STOMP project on codehaus.org, so in the future you will be able to grab updates from there.

For the Flex app we’ll just focus on the code that is needed to connect to ActiveMQ via STOMP and consume the xml that Rails is publishing. To makes things a bit easier, we’ll start with the completed Flex and just walkthrough the code. If you haven’t already download the source for the Flex app. To see what the Flex app looks like click here. As you can see it’s pretty much just a data grid that is used for displaying the sale info.

So, here is the important code, which is all inside the script tags in the Flex app:

[Bindable]
private var sales : ArrayCollection = new ArrayCollection();
 
private var stomp : STOMPClient = new STOMPClient();
private var queue : String = "/queue/Sale";
 
private function init () : void
{
	stomp.connect("localhost", 61613);
	stomp.subscribe( queue );
 
	stomp.addEventListener(MessageEvent.MESSAGE, handleMessages);
	stomp.addEventListener(ReceiptEvent.RECIEPT, handleReceipts);
	stomp.addEventListener(STOMPErrorEvent.ERROR, handleErrors);
 
}
 
private function handleMessages(event : MessageEvent) : void
{
	var incomingMsg : XML = XML(event.message.body);
	var processedSale : ObjectProxy = simplerXMLDecoder(incomingMsg);
	orders.addItem(processedSale);
}
 
private function handleReceipts (event : ReceiptEvent) : void
{
	trace ("Got receipt: " + event.receiptID)
}
private function handleErrors (event : STOMPErrorEvent) : void
{
	trace ("Error: " + event.error.body)
}
 
private function simplerXMLDecoder (x : XML) : ObjectProxy
{
	var xdoc : XMLDocument =  new XMLDocument();
	xdoc.ignoreWhite = true;
	xdoc.parseXML(x.toXMLString());
	var decoder : SimpleXMLDecoder =  new SimpleXMLDecoder(true);
	return decoder.decodeXML(XMLNode(xdoc.firstChild)) as ObjectProxy;
}

Here’s what’s going on in this code.

  • Up near the top we create a new STOMPClient
  • Directly below we specify the destination for the queue that we will be subscribing to, which is the same destination that we specified in messaging.rb above.
  • In the init() method, which is called when the application loads, we connect to the STOMP broker (ActiveMQ) and then subscribe to the queue.
  • We then set up listeners to listen for messages from ActiveMQ.

All of the real action is happening in the handleMessages method.

  • The handleMessages method gets called when the Rails app sends out the xml for a new sale.
  • When a new message is received we take the body of the message (which is the xml from Rails) and use the XMLDecoder class to turn it into a bindable ObjectProxy.
  • Finally, the new sale is added to the sales ArrayCollection, which is the data provider for the data grid in the Flex app.

Getting Everything Up and Running

Alright, now we are actually ready to run something. Assuming that the Rails app and ActiveMQ are still running, all that we need to do is launch the Flex app. You can either build the app yourself from the source files, or you can go in to the source files, open the bin folder and launch StompSalesReport.html.

Now, open a browser and navigate to http://localhost:3000/sales/new

You should see our spartan, but functional, scaffolded interface. Enter some product info and click Create.
Rails Sales Report

Now if you switch back to Flex app, you should see the following:

Flex Sales Report

Pretty exciting stuff. Immediately after the sale was saved to the database, the SaleObserver published it to the queue, where ActiveMQ pushed it out to the Flex app.

One last little tidbit. If you change the code in init() method in the Flex app so that it looks like this:

private function init () : void
{
        var ch : ConnectHeaders =  new ConnectHeaders();
	ch.clientID = "MYTOTALLYUNIQUECLIENTID";
	stomp.connect("localhost", 61613, ch);
 
	var sh : SubscribeHeaders = new SubscribeHeaders();
	sh.amqSubscriptionName = "MYSUBSCRIPTION";
	stomp.subscribe( queue, sh );
 
	stomp.addEventListener(MessageEvent.MESSAGE, handleMessages);
	stomp.addEventListener(ReceiptEvent.RECIEPT, handleReceipts);
	stomp.addEventListener(STOMPErrorEvent.ERROR, handleErrors);
}

By passing a client-id header on connect and a subscriptionName header on subscribe we create what is known as a durable subscriber.

If you compile the Flex app, launch it and then close it. Then go in back to the Rails app and create a new sale, relaunch the Flex app and you should immediately see the sale show up.


Whew! That’s it. This post was way too long. I am thinking that it may be easier to cover this stuff in a screencast. Let me know in the comments if you think a screencast would be a good idea.

As always, let me know if you have any questions.

14 Responses to “Publish\Subscribe Messaging with Flex and Rails using Apache ActiveMQ, ActiveMessaging, and STOMP”

  1. flexonrails.net » Blog Archive » Flex chat application that uses Apache ActiveMQ and STOMP says:

    [...] follow on my last post, here is a little Flex chat application that uses Apache ActiveMQ and the ActionScript 3 STOMP [...]

  2. Andrew Kuklewicz says:

    Really excellent example, and it opens the door to all kinds of ideas with the improved as3/flex support for stomp. Very cool. I sent a link out to the activemessaging list, and put linked to you blog on the activemessaging wiki.

    Did you have any thoughts about having the client flex app connecting remotely to the activemq server? The port is pretty high, but I wonder if you would run into the same firewall issues that came up with juggernaut (http://juggernaut.rubyforge.org/) which switched to the 443/ssl port as it is usually open.

  3. Derek Wischusen says:

    Hi Andrew – Thanks for the comment and all the cool work that you are doing with ActiveMessaging.

    Yeah, ports can be an issue, especially with Flash which imposes its own restrictions. In a future release of the AS3 Stomp client I’ll definitely need to make sure that externalize the config info for the port and host.

    Derek

  4. Vixiom Axioms » Everybody's chatting about Flex says:

    [...] – Derek Wischusen has his messages moving atop Rails, Apache ActiveMQ, ActiveMessaging, and STOMP (post 1, post 2) – Alex McCaw is the creator of Juggernaut which can use Flex or Ajax to push messages on [...]

  5. JRadical says:

    ps: For Non-Durable DO NOT send; or under load ActiveMQ goes to sleep…

    ch.clientID = “MYTOTALLYUNIQUECLIENTID”;
    sh.amqSubscriptionName = “MYSUBSCRIPTION”;

    Great Work!

  6. ?? says:

    I learn much from this post.thanks for the Great Work!
    I translated it into chinese,view here.welcome your words.
    ???????????????????

  7. flexonrails.net » as3Stomp - Project site and source code says:

    [...] little while ago I posted about my ActionScript 3 implementation of the STOMP protocol.  Well, I am just now getting around to posting that I created a google project site and released [...]

  8. DoX says:

    Do you think it would be possible to “stomp over rtmpt” so the client could be able to connect through restricting proxies ?

  9. Hans says:

    A note and correction on step 14:

    In order to activate an observer, list it in the config.active_record.observers configuration setting in your config/environment.rb file.

    config.active_record.observers = :model_observer

    Observers will not be invoked unless you define these in your application configuration.

    Otherwise, great post! :-)

  10. Recent Links Tagged With "flex2" - JabberTags says:

    [...] public links >> flex2 flexonrails.net " PublishSubscribe Messaging with Flex and Rails Saved by JeannieWithoutBottle on Sat 18-10-2008 Switching from Eclipse Flex 2 Plugin to Flex [...]

  11. ?? » Blog Archive » ?Flex?Rails?????/??????? says:

    [...] ???PublishSubscribe Messaging with Flex and Rails using Apache ActiveMQ, ActiveMessaging, and STOMP [...]

  12. patate says:

    Great post, but sadly, could not get it to work after 15-20 hours of work due to the socket policy restrictions with flex. If you could please clarify as to how the policy file should be served to avoid sandbox security violations, please do! The AS stomp client just wont connect!!

  13. John T says:

    Great, great information. Stomp/ActiveMQ has saved my Flex application on many levels. However, when the applications are run in a browser with Flash 10, it does not connect because of the sercurity policies. We’ve exhausted all efforts to set the correct security policy and play with crossdomain.xml file settings. Have you had any luck to get this to work in a browser (http://... and not file://…) with Flash 9 or better?

  14. John T says:

    Project does not look very active, but if anyone reads this, AMQ with Flex 3 works great and fast. Perfect for our situation. To get over the security issue (and a week working with Adobe on this), you need to run a flash policy server (FPS) on the host where AMQ is at. The FPS listens in port 843 for an XML request and then simply returns a dynamic cross-domain-policy XML body like crossdomain.xml. There are a couple examples on the web in PHP and Pearl that can be used as a basis. Might need to enhance these to be “production” ready.

Leave a Reply

Cialis canada no prescription
Buying cialis
Tramadol no prescription overnight delivery
Phentermine 37.5 buy online
Best prices for cialis
Where to buy phentermine cheap
Buy xanax cheap online
Order cheap viagra online
Cheap xanax for sale
Tramadol free shipping
Viagra purchase uk
Viagra tablets for sale
Cheap generic valium
Cheapest levitra
Generic propecia
Cheap propecia without prescription
Generic xanax xr
Tramadol for sale
Buy cialis in the uk
Xanax no prescription required
Buying cialis online without a prescription
Buy generic valium
Buying tramadol in uk
Purchase viagra online without prescription
Purchase tramadol online
Propecia price australia
Buying viagra in new zealand
Viagra buy online no prescription
Viagra price canada
Buy phentermine online without prescription
Buy generic phentermine online
Phentermine online uk
Phentermine 37.5mg side effects
Cialis over the counter
Viagra ordering
Viagra generic
Buy valium cheap online
Viagra cheapest
No prescription valium
Buy xanax canada
Buy propecia cheap
Prescription viagra canada
Valium 10 mg
Tramadol dosage
Cialis 20 mg dosage
Viagra pharmacy uk
Order xanax online
Generic viagra 100mg
Where to buy viagra in england
Blood pressure and prednisone
Levitra online cheap
No prescription cialis online
Cheap valium online
Viagra discount coupons
Overnight tramadol no prescription
Cheapest cialis price
Cheap phentermine without prescription
Buy cialis viagra
Xanax no rx
Discount viagra pills
Viagra without prescription uk
Cialis price
Prednisone 40 mg
Where can i buy viagra without prescription
Cheapest cialis professional
Cialis online canadian pharmacy
Buy viagra in canada online
Phentermine 37.5 wholesale
Best price on phentermine
Order tramadol online overnight
Viagra 50 mg online without prescription
Xanax for sale without prescription
Order tramadol overnight
Buy viagra uk online
Levitra samples
Phentermine purchase online
10mg prednisone
Tramadol without prescription
Get tramadol prescription
Valium cheapest
Viagra canada mastercard
Purchase phentermine
Buy viagra online in australia
Prednisone tablets
Prescriptions for phentermine
Viagra dosage information
Generic xanax
Order phentermine online no prescription
Australia viagra prescription
Where to buy cialis safely
Tramadol online no prescription overnight
Where can i buy viagra in the uk
Propecia usa
Overnight delivery viagra
Buy phentermine 37.5mg online
Viagra 50mg side effects
Cialis 20mg
Viagra canada prices
Phentermine with no prescription
Prescription viagra uk
Buy cheap viagra online uk
Purchase phentermine online
Real phentermine without prescription
Buy xanax 2mg no prescription
Discount viagra online
Free cialis online
Cialis ordering
Buy propecia
Order cheap phentermine
Buy generic xanax no prescription
Online valium without prescription
Cheap levitra no prescription
Buy phentermine no script
Best way to buy viagra online
Tramadol cod delivery
Buy xanax overnight
Cost of viagra 50mg
Low price cialis
Buy valium without prescription uk
Tramadol india
Order viagra without prescription
Ordering propecia from canada
Dose of xanax
Propecia best prices
Xanax bars side effects
Viagra indian pharmacy
Cialis discount price
Cheap cialis india
Tramadol cheapest
Cheapest online cialis
Pharmacy tramadol
Where can i buy viagra without a prescription
Generic xanax no prescription
Canada pharmacy valium
Dosage of xanax
Brand name cialis
Generic viagra online without prescription
Tramadol no prescription required
Cialis for sale
Cialis side effects
Viagra in the uk
Prednisone tablets 10 mg
Buy levitra online canada
Valium drug side effects
Low cost cialis
Cheap 37 5 phentermine
Viagra in usa
Viagra cheap no prescription
Cialis 20mg side effects
Prednisone dosages
Purchase tramadol without prescription
Generic tramadol
Best viagra dose
Viagra to buy
Get viagra
Where to buy propecia in canada
Xanax 0.5 mg
Xanax no prescription overnight
100mg tramadol effects
Prescription valium
Valium pill 10mg
Buy female viagra without prescription
Buy viagra in england
Phentermine hcl no prescription
Viagra generic cheap
Buy viagra online cheap
Levitra 20mg
Brand viagra cheap
Buy pfizer viagra without prescription
Viagra prescription cost
Purchase cialis without a prescription
Viagra online without prescription reviews
Propecia information
Buying prednisone online
Buying xanax online without prescription
Valium from india
Viagra online uk
Levitra purchase
Where to buy cialis online
Viagra express delivery
Valium no rx
Buy tramadol cod
Overnight xanax delivery
Buy brand name viagra
Levitra on sale
Side effects of viagra
Viagra fast delivery
Cialis medication
2.5mg cialis
40 mg prednisone side effects
Free cialis samples
Viagra canadian online pharmacy
Ordering cialis online
Valium online pharmacy
Xanax bars effects
Viagra super active
Discount viagra india
Authentic phentermine 37.5
Xanax overnight cod
Xanax 1mg side effects
Viagra pharmacy prices
Viagra in france
Phentermine without a prescription
How to buy phentermine online
Phentermine hcl without prescription
Cheap xanax bars
Prescription free viagra
Buy generic cialis uk
Phentermine diet pills without prescription
Cialis samples canada
Buy phentermine online no prescription
Cialis order canada
Tramadol prescription online
Xanax buy uk
Cialis uk sales
Propecia 1mg generic
Buy generic cialis
Cheap cialis pills
Propecia ireland
Buy viagra online in ireland
Tramadol pharmacy
Xanax bars dosage
Propecia online uk
Buy phentermine hcl 37.5 no prescription
10mg valium effects
Purchase levitra online
Buy viagra from canada
Where to buy cialis without prescription
Xanax with no prescription
Buy valium no rx
Xanax price per pill
Buy viagra uk no prescription
Buy cialis online from canada
Generic viagra super active
Xanax generic dosage
Valium generic
Genuine viagra online
Propecia price
Buying valium in spain
Cialis soft tabs online
Levitra us
Viagra lowest prices
Cheap cialis
Tramadol without prescription overnight delivery
Online prescriptions xanax
Phentermine online free shipping
Buy generic propecia uk
2mg xanax no prescription
Generic cialis overnight
Viagra discount prices