Feb 11 2008
Server push with Ruby on Rails using Flex, JRuby, and BlazeDS
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.






