Feb 18 2008

Integrating Flex and RabbitMQ using STOMP

Tag: Flex, Messaging, RabbitMQ, STOMPDerek Wischusen @ 12:21 am

An experimental STOMP adapter was recently released for RabbitMQ. This means that it is now possible for Flex/Flash apps to communicate with RabbitMQ using the ActionScript 3 STOMP client. The following is a simple demonstration of how to get these technologies to work together.

First, let’s start with a quick description of RabbitMQ and STOMP.

RabbitMQ:

RabbitMQ is a complete and highly reliable Enterprise Messaging system. The RabbitMQ client libraries and broker daemon can be used together to create an AMQP network, or used individually to bring the benefits of RabbitMQ to established networks.

Packages/installers are available for all major operating systems and platforms. RabbitMQ can also be deployed as a VMWare/Debian virtual appliance.

Features:

* A complete, conformant and interoperable implementation of the published AMQP specification
* Based on a proven platform, offering exceptionally high reliability, availability and scalability
* Good throughput and latency performance that is predictable and consistent
* Compact, easily maintainable code base, for rapid customisation and hot deployment
* Extensive facilities for management, monitoring, control and debugging
* Licensed under the open source Mozilla Public License

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.

As you can see from its description, the primary protocol that RabbitMQ uses is AMQP. If you’d like to learn more about AMQP, then check out this site.

There is an ActionScript 3 client for AMQP that is being developed by Ben Hood. You can read more about this client and learn how to use it by checking out this post on Ben’s site.

Alright, let’s get started with the example of how to use as3-stomp client with RabbitMQ.

1. Follow the steps in this tutorial to get RabbitMQ running with the STOMP adapter.

2. Download the project files for the Flex app.

This project consists of two separate Applications: the ImageSender and the ImageReceiver. The project file also contains the compiled as3-stomp library, so you do not need to download it separately.

3. Import the project into Flex Builder. (This step is optional. Alternatively you could unzip the project file and run the apps by opening the ImageSender.html file and the ImageReceiver.html file in the bin-debug folder.)

4. Launch both applications.

Before we proceed let’s take a quick look at what happened when we launched the apps.

Both apps have an init method that gets called when the application first the creationComplete event. Here is what this method looks like in the ImageSender app:

private function init () : void
{
    var ch: ConnectHeaders = new ConnectHeaders();
    ch.login = "guest";
    ch.passcode = "guest"
    stomp.connect("localhost", 61613, ch);
}

In this code we create a ConnectHeaders object that we use to set the login and passcode for this session. By default, RabbitMQ creates a user called “guest” with password “guest”. We then call connect on the stomp client. The stomp client was instantiated using an MXML tag like so,

<stomp:Stomp id="stomp"  />

The code for the init method in the ImageReceiver app looks pretty much the same except that it contains one more line.


private var destination: String = "/queue/images";

private function init () : void
{
    var ch: ConnectHeaders = new ConnectHeaders();
    ch.login = "guest";
    ch.passcode = "guest"
    stomp.connect("localhost", 61613, ch);
    stomp.subscribe( destination );
}

On the final line in the init method we call the subscribe method on the stomp client. By calling this method we tell the stomp broker (RabbitMQ in this case) that we want to consume messages that are sent to this destination.

The code where we instantiate the stomp client in the ImageReceiver is also pretty much the same as it is in the ImageSender,

<stomp:Stomp id="stomp" message="handleMessages(event)"  />

The only difference is that we set message event property so that every time a message event is fired the handleMessages method gets called.

Ok, back to the demo.

5. Go to the ImageSender app and click the Images button.

6. Select an image from the list and use the mouse cursor to draw some lines on the image.

Stomp Image Share ImageSender

7. Click Send Image.

8. Go to the ImageReceiver app and you should see the image that you sent.

Stomp Image Share ImageSender

Ok, back to the code. When you clicked the Send Image button the sendImage method was called,

private function sendImage():void
{
    var image: ByteArray = ImageSnapshot.captureImage(canvas).data;
    stomp.send(destination, image);
}

In this method we use the ImageCapture class (FYI: this class is only available in Flex 3) to capture the image data from that canvas that contains our image and store it in a ByteArray. We then call send on the stomp client to send this data to the “/queue/images” destination.

RabbitMQ receives this message and sends it along to any consumer that are subscribed to this destination, including our ImageReceiver app.

When the stomp client in the ImageReceiver receives the message it fires a message event and calls the handleMessage method.

private function handleMessages(event : MessageEvent) : void
{
    var bd: BitmapData = new BitmapData(canvas.width, canvas.height);
    var loader : flash.display.Loader = new flash.display.Loader();
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBytesLoaded);
    loader.loadBytes(event.message.body);
    function onBytesLoaded (event : Event) : void
    {
        var content : DisplayObject = LoaderInfo( event.target ).content;
        bd.draw( content );
        canvas.graphics.beginBitmapFill(bd);
        canvas.graphics.drawRect(0,0, canvas.width, canvas.height);
        canvas.graphics.endFill();
    }
}

This method grabs the body of the message (which is the ByteArray containing the image data) and draws it on to a canvas.

That’s it. As always, let me know if you have any questions. And if you encounter any bugs that appear to be in the as3-stomp client, please submit a report here.


Nov 23 2007

as3Stomp – Project site and source code

Tag: AS3, ActionScript, ActiveMQ, ActiveMessaging, STOMP, Server PushDerek Wischusen @ 7:48 pm

A 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 the source.   This version is slightly updated from the one that was included in my example code in the previous post.

 If you have any questions about this project, or if you would like to contribute, please let me know.  Please post any bugs to this issue list.


Jul 28 2007

Flex chat application that uses Apache ActiveMQ and STOMP

Tag: AS3, ActiveMQ, Messaging, STOMP, Server PushDerek Wischusen @ 10:55 pm

To follow on my last post, here is a little Flex chat application that uses Apache ActiveMQ and the ActionScript 3 STOMP library that I have been working on.

You can get the source for the application here.

You will need to download and install ActiveMQ to run this app. Installing ActiveMQ is pretty straight-forward. You can grab one of the latest snapshots here, and then follow the instructions posted here.

Here are some basic instructions to get ActiveMQ up and running:

  1. Download an unzip to the directory of your choice.
  2. Open a command-line and navigate to the bin folder inside activemq
  3. Run the activemq application inside the bin folder. (e.g., $ activemq/bin/activemq).

Once you’ve got ActiveMQ running.  Go ahead a launch a couple instances of the Flex chat app.  Login to each one and start chatting.  For example,

Chat 1

Chat 2_1

You can also see the chat messages that come from the chat demo that comes with ActiveMQ.

In your browser, go to: http://127.0.0.1:8161/demo/chat.html, login and send a chat message.  For example,

AMQ Chat 2

Chat 3


Jul 28 2007

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 &lt; 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 &lt; 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.


Tramadol medication
Generic xanax
Viagra generic
Cheapest cialis price
Cheap cialis
Xanax 1 mg dose
Cialis uk sales
Buy generic cialis online
Phentermine without a prescription
Ordering cialis online
Dosage of xanax
Prednisone tablets 10 mg
Best price tramadol
Viagra cheapest
Viagra tablets for sale
Viagra discount coupons
Buy valium no rx
Buy xanax canada
Cheap phentermine without prescription
Tramadol online no prescription overnight
Viagra india price
Cialis medication
Buy phentermine no rx
Where to buy phentermine cheap
Cialis price
Where can i buy viagra in the uk
Discount viagra india
Buy viagra uk no prescription
Tramadol no prescription overnight delivery
10mg prednisone
Buying tramadol in uk
Tramadol for sale
Where to buy viagra in england
Cheap cialis soft tabs
Buying viagra in london
Phentermine buy uk
Buy cheap viagra online uk
Viagra professional online
Best way to take tramadol
Xanax online cheap
Buy cialis brand
Viagra online without prescription reviews
Buy phentermine hcl 37.5 no prescription
100mg tramadol online
10mg valium effects
Viagra no prescription online
Order tramadol online cod
Cialis samples canada
Propecia best prices
Tramadol india
Viagra canada online
Xanax overnight cod
Viagra 50mg side effects
Propecia price
Get viagra prescription
Order tramadol cod
Ordering propecia from canada
Cheap generic valium
Cialis canada no prescription
Levitra price
Xanax 1mg
Viagra pills for sale
Pfizer viagra price
Buy viagra 100mg
Propecia generic online
How to buy phentermine online
Valium generic
Viagra 50 mg online without prescription
100mg tramadol effects
Generic xanax xr
Low price cialis
Propecia usa
Side effects of viagra
Buy viagra online in ireland
Viagra in the uk
Phentermine 37.5 wholesale
Australia viagra online
Where can i buy viagra without prescription
Mail order phentermine
Buy generic valium online
Viagra lowest prices
Buy cialis in the uk
Buy levitra
Cialis 20 mg dosage
Discount viagra online
Low price viagra
Phentermine cheap online
Valium online fast delivery
Levitra online cheap
Buy viagra online uk no prescription
Where to buy viagra online
Propecia generic canada
Buy cheap valium online
Cheap cialis pills
Discount viagra pills
Order phentermine online no prescription
Valium without prescription
Generic levitra uk
Buy viagra in canada online
Best viagra dose
Buy xanax 2mg no prescription
Xanax bars effects
Xanax no rx
Fedex tramadol
Buying prednisone online
Buy propecia online without a prescription
Phentermine purchase online
Generic viagra sales
Prescription phentermine online
Cialis purchase online
Cialis for sale
Xanax price per pill
Where to buy cialis without prescription
Cheapest place to buy viagra online
Order tramadol overnight
Generic propecia
Purchase xanax
Cialis order online
Best levitra prices
Buy female viagra without prescription
Buy viagra in england
Viagra canadian online pharmacy
Tramadol prescription online
Get viagra
Online prescription tramadol
Tramadol cod delivery
Generic tramadol
Best viagra alternative
Viagra canada prices
No prescription cialis online
Propecia online uk
Cialis 10mg side effects
Xanax bars dosage
Purchase phentermine without prescription
Best prices for cialis
Levitra us
Cheap 100mg viagra
Generic viagra for sale
Viagra in the philippines
Cheap valium online
No prescription valium
Xanax 1mg side effects
Tramadol pharmacy
Blood pressure and prednisone
Cheap levitra no prescription
Viagra online shop
Buy cialis viagra
Buy xanax overnight
Propecia cheap
Tramadol no prescription required
Prednisone 20mg side effects
Phentermine 37.5mg
Phentermine 37.5mg side effects
Propecia cost
Authentic phentermine 37.5
Where to buy cialis online
Xanax bars side effects
Viagra ordering
Valium no rx
Cialis ordering
Cheapest levitra
Overnight tramadol no prescription

2.5mg cialis
Buying cialis online without a prescription
Buy generic propecia uk
Order xanax cod
Cheap xanax bars
Buying viagra in new zealand
Xanax buy uk
Viagra in usa
Overnight delivery viagra
Purchase tramadol online
Prescription viagra canada
Buy viagra online in australia
Viagra shop online
Buy tramadol cod
Viagra prescription cost
Buy phentermine 37.5mg online
Phentermine 37.5 buy online
Phentermine diet pills without prescription
Prednisone online
Viagra online purchase in india
Cheap generic viagra
Generic cialis tadalafil
Australia viagra prescription
Phentermine canadian pharmacy
Cheap xanax for sale
Where to buy cialis safely
Generic cialis overnight
Order prednisone no prescription
Cialis 20mg
Cialis prices uk
Levitra online
Viagra dosage information
Genuine viagra online
Purchase viagra online without prescription
Valium drug side effects
Cheap cialis india
Viagra canada mastercard
Cialis over the counter
Where to buy levitra online
Propecia price australia
Where can i buy viagra without a prescription
Cialis soft tabs online
Propecia 1mg generic
Cialis discount price
Buy xanax cheap online
Viagra online cheap
Free samples of cialis
Canada viagra
Brand name cialis
Tramadol cheapest
Order xanax online
Viagra without prescription uk
Buy viagra australia
Levitra online buy
Cialis online canadian pharmacy
How to buy valium without a prescription
Buying levitra without prescription
Order cheap viagra online
Buy valium europe
Generic viagra super active
Best price cialis
Viagra sale uk
Buy phentermine no script
Valium without prescription uk
Buy tramadol hydrochloride
Viagra express delivery
Tramadol without prescription
Generic xanax no prescription
Xanax for sale without prescription
Cheap cialis viagra
Phentermine hcl without prescription
Tramadol dosage
Xanax generic dosage
Buy tramadol hcl
Overnight xanax delivery
Buy generic valium
Prednisone dosages
Buy viagra from canada
Viagra online uk
Buy cialis uk
Discount viagra usa
Cialis prescription cost
Cheap propecia without prescription
Propecia generic cost
Cialis order canada
40 mg prednisone side effects
Buy xanax online without prescription