Feb 11 2008

Server push with Ruby on Rails using Flex, JRuby, and BlazeDS

Tag: ActiveMQ, ActiveMessaging, Flex, Flex and Rails, JRuby, Messaging, Server Push, blazedsDerek Wischusen @ 5:32 am

In a previous post I discussed how you can integrate Flex and Scala/Lift using BlazeDS.  In this post I’ll show that it’s also possible to get Rails running on BlazeDS using JRuby.

Here is what I am using for this example:

You don’t really need Netbeans, but I’ve found that it makes things a bit easier.

For this example I am going to assume you have a basic understanding of Flex and Rails.  That said, if anyone has a question, not matter how basic, please feel free to ask.

Here are the source files if you want to follow along:

—– 

Ok, first lets get the Rails app set up.

1. Create a new Rails app called RoRBlaze.

2. Generate a controller called Greeting with an index view.  i.e.,

> ruby script/generate controller Greeting index

3.  Open up your newly generated greeting.rb file and add the following code:

class GreetingController < ApplicationController
  include Java
  import "flex.messaging.MessageBroker"
  import "flex.messaging.messages.AsyncMessage"
  import "flex.messaging.util.UUIDUtils"

  @@msgBroker = MessageBroker.getMessageBroker(nil)
  @@clientID = UUIDUtils.createUUID()

  def hello
    @msg = AsyncMessage.new()
    @msg.setDestination("notifications")
    @msg.setClientId(@@clientID)
    @msg.setMessageId(UUIDUtils.createUUID())
    @msg.setTimestamp(Time.new.to_f)
    @msg.setBody("Hello from Rails")
    @@msgBroker.routeMessageToService(@msg, nil)
    render :text => "Greeting Sent"
  end
end

4. Open view/greeting/index.rhtml and add a button to it like so,

<%=button_to "Send Greeting to Flex", :action=>"hello" %>

5. Go to the BlazeDS folder and  locate the following two .jar files in tomcat\webapps\blazeds\WEB-INF\lib:

  • flex-messaging-common.jar
  • flex-messaging-core.jar

6. Copy these .jar files into the lib folder in your Rails app (keep this folder open, you’ll need the more of the .jars in a moment).

7. In your Rails app open up config/environment.rb and add the following to the bottom of the file:

Dir["#{RAILS_ROOT}/lib/**/*.jar"].each do |jar|
  require jar
end

Alright, thats pretty much all of the Ruby code for this simple example.  Now we need to use the Goldspike Rails plugin to modify our Rails app so that it can run in a Java server (like Tomcat or Jetty or Glassfish, etc)

8.  From a command line, go to the root of your Rails app and install the Goldspike plugin:

> ruby script/plugin install http://jruby-extras.rubyforge.org/svn/trunk/rails-integration/plugins/goldspike

9. WARify you Rails app using the following rake command:

> rake war:standalone:create

Assuming that Goldspike did its job, you should now have a folder called WEB-INF in the root of you Rails app.  We need to add a few file to this folder to get BlazeDS working.

10. Copy the .jars from BlazeDS\tomcat\webapps\blazeds\WEB-INF\lib into RoRBlaze\WEB-INF\lib

11. Copy the folder BlazeDS\tomcat\webapps\blazeds\WEB-INF\flex into RoRBlaze\WEB-INF

12. Open up the web.xml file in blazeds\WEB-INF and merges its contents into the web.xml file in RoRBlaze\WEB-INF.  Click here to see what the final file should look like.

13. Open up RoRBlaze\WEB-INF\flex\messaging-config.xml and modify it so that it looks like this (click to view the file).  The key thing to note here is that we added a messaging destination called “notifications”.  This is the destination that the Greeting controller publishes to and it is the destination that our Flex app will subscribe to.

14. Open up RoRBlaze\WEB-INF\flex\services-config.xml and modify it so that it looks like this (click to view the file).  The key thing to notice in this file is that we defined a streaming channel called my-streaming-amf that BlazeDS will use to push messages over a persistent, streaming HTTP channel.

That’s it for the Rails app.  Now let’s create the Flex app.

—–

1. Create a new Flex Project (File -> New -> Flex Project)

2. Fill in the rest as follows:

  • Project name: RoRBlaze
  • Application type: Web Application
  • Application server type: J2EE
  • Use remote object access service: check this
  • Root folder: RoRBlaze  (the root folder of your Rails app)
  • Root URL: http://localhost:8080/RoRBlaze/
  • Context root: /RoRBlaze
  • Output folder: RoRBlaze\public
  • Output folder URL: http://localhost:8080/RoRBlaze

3. Open up RoRBlaze.mxml and edit it like so:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical"
	creationComplete="consumer.subscribe()">

    <mx:Script>
        <![CDATA[
          	import mx.messaging.events.MessageEvent;

            private function messageHandler(message: MessageEvent): void
            {
                pushedMessage.text = message.message.body as String;
            }
        ]]>
    </mx:Script>

    <mx:Consumer
    	id="consumer"
    	destination="notifications"
    	message="messageHandler(event)"
    	channelConnect="trace(event)"
        channelFault="trace(event)"
        fault="trace(event)" />

    <mx:TextInput id="pushedMessage" width="300"/>
</mx:Application>

That’s it for the Flex app.  Let’s test everything out.

—–

1. Open a terminal and go to the root of your Rails app.  Then use Goldspike to boot up your Rails app in a Jetty server:

> rake war:standalone:run

In a few short seconds your Rails app should  be up and running.

2. Launch the Flex app.

3.  Open a browser and enter the following URL: http://localhost:8080/RoRBlaze/greeting

You should see a single button that says “Send Greeting to Flex”

4. Click the button.

Upon clicking the button you should see the browser display “Greeting Sent” and you should see “Hello from Rails” appear in the text input in your Flex app.

That’s it.  Assuming that everything worked properly, the Rails app should have pushed an AMF encoded message to Flex using a persistent streaming HTTP channel created by BlazeDS.

One importatant thing to take note off is that this technique could be useful to you even if you aren’t planning on using Flex/Flash as your presentation layer.  You could use a Juggernaut style approach and push messages from Rails to an embedded Flash player whose only job is to pass those messages along to the browser.

This example demonstrates a very simple way to integrate Flex, Rails, and BlazeDS.  I think the ideal way to integrate these technologies would be to use the ActiveMessaging plugin for Rails, since both ActiveMessaging and BlazeDS have JMS adapters which they could use to integrate with a more robust messaging system like ActiveMQ.  If I can find some time in the near future, and if there is any interest, I’ll do a follow up post on this.


Mar 05 2007

JRuby + RED 5 = Ruby + RTMP

Tag: JRuby, RTMP, Red 5Derek Wischusen @ 12:51 am

JRuby is, in my opinion, one of the most exciting projects out there. Primarily because it makes it possible for Ruby developers to take advantage of all the technologies that have been built in Java. In particular, it makes it possible to take advantage of one of the other most exciting projects out there: Red 5.

Red5 is an Open Source Flash Server written in Java that supports:

  • Streaming Audio/Video (FLV and MP3)
  • Recording Client Streams (FLV only)
  • Shared Objects
  • Live Stream Publishing
  • Remoting

Red 5 is, or very soon will be, a viable free, open source alternative to Flash Media Server. Most important of all to the Ruby community is the fact that Red 5 recently added a scripting framework that makes it possible to use it with Ruby (via JRuby), as well as Javascript (via Rhino), Python (via Jython), and Groovy. Though, even if there was no scripting framework in Red 5, it should now be relatively easy to do using a simple wrapper class in Java that loads your Ruby classes using the new scripting framework in Java 6.

To get started with Red 5 and Ruby, first download a copy of Red 5, then check out this tutorial by Paul Gregoire.

If you want to try to use Rails with from the scripting framework in Red 5, then be sure to read the ‘Gotchas’ at the bottom of this page.

More to come on this in future posts.