Vixiom Axioms

August 23, 2006

Flash Remoting for Rails Tutorial

Filed under: ActionScript, Flash, Ruby on Rails Alastair @ 7:22 pm

Ever since I’ve been using Rails I’ve missed one important tool from my webdev toolbox, Flash Remoting. I’ve been getting by with XML but it’s just not the same and it changes the way you approach things ("If all you have is a hammer everything looks like a nail"). Remoting can pass objects, arrays, strings etc. straight to Flash as native data types which avoids XML sit-ups (as the Rails folk would say). Remoting uses AMF (Active Message Format) which comes across as bytes so it’s faster than XML. Yesterday my prayers where answered as the Midnight Coders released WebORB for Ruby on Rails.

Their examples use Flex 2.0 which is the future of of Rich Internet Apps, however requiring Flash player 9.0 in all situations isn’t too user friendly (like on a hybrid HTML page) and since Remoting has been available since Flash player 6 (pre Ajax craziness) you should try to publish for only the features you need. That said I’m a design Nazi, and can’t get enough of anti-alias for readability, so I publish for Flash 8 as much as possible (Adobe claims 86.0% user penetration for player 8).

If you’ve never used Flash Remoting before you need to install the Remoting Components.

We’ll be hooking a Flash MP3 player up to a Rails back-end (which in real life would have some kind of CMS for adding MP3s). For this tutorial I ported a MP3 player I made for Buchanan a local Orange County band. The original uses XML as the data is static. I’ve replaced the Buchanan playlist with a “Midnight” themed one in honor of the hard work Midnight Coders put in to deliver Remoting on Rails for free!

On to the tutorial… a zip file of all the source code is here. All the flash files are in mp3app/fla.

Create a new rails app called ‘mp3app’

> rails mp3app
> cd mp3app

Install Weborb for Rails

> ruby script/plugin install http://themidnightcoders.net:8089/svn/weborb

Create a MySQL development database ‘mp3app_development’ with a table to hold your tracks

CREATE TABLE `tracks` (
  `id` int(11) NOT NULL auto_increment,
  `title` varchar(50) NOT NULL default ,
  `artist` varchar(50) NOT NULL default ,
  `album_art` varchar(50) NOT NULL default ,
  `filename` varchar(50) NOT NULL default ,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

insert into `tracks` values(‘1′,‘After Midnight’,‘Eric Clapton’,‘clapton.jpg’,‘AfterMidnight.mp3′),
 (‘2′,‘Midnight Train to Georgia’,‘Gladys Knight’,‘gladys.jpg’,‘MidnightTrainToGeorgia.mp3′),
 (‘3′,‘Midnight In A Perfect World’,‘DJ Shadow’,’shadow.jpg’,‘MidnightInAPerfectWorld.mp3′),
 (‘4′,‘Two Minutes to Midnight’,‘Iron Maiden’,‘maiden.jpg’,‘TwoMinutesToMidnight.mp3′);

Create a ‘Track’ model

> ruby script/generate model Track

Create a remoting service inside of the app/services directory called ‘TrackService.rb’

require ‘weborb/context’
require ‘rbconfig’

class TrackService
   def getTracks
     tracks = Track.find(:all)
   end
end

If you’ve ever used AMFPHP or one of the .NET flavors of remoting you probably said "That’s it!?!". This is by far the shortest remoting service I’ve ever written. You should now be able to start the local lighttpd/WebBrick server and test the mp3Player.fla file locally. I’ve left all my traces in so you can see what’s going on.

Next on to Flash. There’s a few frameworks out there for Flash apps (ARP, Cairngorn) but for relatively simple things like our MP3 Player they’re overkill. I have my own lightweight framework (if it even qualifies as a framework, it’s only two files) that is a kind of MVC where the Model is a Remoting class that hooks up to the back-end (PHP, .NET, or now Rails) a Controller that is actually the .fla file, and a View class. The base Remoting and View classes have event dispatching for communicating with each other through the controller and that’s about it, any other functionality is extended with other classes.

The base Remoting class looks like this

import mx.remoting.Service;
import mx.services.Log;
import mx.remoting.PendingCall;;
import mx.rpc.RelayResponder;
import mx.rpc.FaultEvent;
import mx.rpc.ResultEvent;
import mx.remoting.debug.NetDebug;
import mx.utils.Delegate;

class com.vixiom.remoting.Remoting
{
    private var gatewayURL:String;
    private var servicePath:String;

    private var svc:Service;

    function dispatchEvent() {};
    function addEventListener() {};
    function removeEventListener() {};

    /**
    * Constructor
    *
    *   @param      gURL    gatewayURL
    *   @param      sp      service path
    *   @param      u       username
    *   @param      p       password
    *
    */
    public function Remoting(gURL, sp, u, p)
    {
        gatewayURL = gURL;
        servicePath = sp;

        // initialize as a broadcaster
        mx.events.EventDispatcher.initialize(this);

        // create a new service
        svc = new Service (gatewayURL, null, servicePath, null, null);

        // credentials
        if (u != undefined && p != undefined) {
            svc.connection.setCredentials(u, p);
        }

    }

    /**
    * Global fault event
    */
    function handleRemotingError(fault:FaultEvent):Void
    {
        mx.remoting.debug.NetDebug.trace({level:“None”, message:“Error: “ + fault.fault.faultstring });
    }

    /**
    * Event dispatcher
    *
    *   @param      d       data
    *   @param      et      eventType
    *
    */
    function dispatch(d, et)
    {
        // broadcast message
        var eventObj:Object={target:this,type:et}
        eventObj.data = d;
        dispatchEvent(eventObj);
    }

}

This is the base View class

import mx.utils.Delegate;

class com.vixiom.view.View
{
    private var target:MovieClip;

    function dispatchEvent() {};
    function addEventListener() {};
    function removeEventListener() {};

    /**
    * Constructor
    *
    *   @param  t   target (target timeline: _root || a mc)
    */
    public function View (t:MovieClip)
    {
        target = t;

        // initialize as a broadcaster
        mx.events.EventDispatcher.initialize(this);
    }

    /**
    * Event dispatcher
    *
    *   @param      d       data
    *   @param      et      eventType
    *
    */
    function dispatch(d, et)
    {
        // broadcast message
        var eventObj:Object={target:this,type:et}
        eventObj.data = d;
        dispatchEvent(eventObj);
    }
}

For the MP3 Player I extended the Remoting class as shown below. You don’t have to keep your classes in packages (com.vixiom.remoting…) but it helps to keep them organized. ‘var pc:PendingCall = this.svc.getTracks();‘ is the line that makes the remoting call to Rails (it corresponds to ‘getTracks‘ in our TrackService.rb class). My class has a ‘tracks’ object and it receives the tracks object straight from ruby ‘tracks = re.result;‘. I’ve commented out the line ‘this.svc.connection.setCredentials(u, p);‘ as that’s for creating secured remoting calls. The last line ‘dispatch(tracks, "onGetTracks");‘ uses even dispatching to pass data to the view.

import mx.remoting.*;
import mx.rpc.*;

class com.vixiom.remoting.RemotingMp3 extends com.vixiom.remoting.Remoting
{
    // tracks holder object
    private var tracks:Object;

    //////////////////////////////////////////////////////////////////////
    //
    // Constructor (gatewayURL, servicePath, userid, password)
    //
    //////////////////////////////////////////////////////////////////////

    public function RemotingMp3 (gURL, sp, u, p)
    {
        super(gURL, sp);
        // this.svc.connection.setCredentials(u, p);
    }

    //////////////////////////////////////////////////////////////////////
    //
    // Get tracks with handler (onGetTracks)
    //
    //////////////////////////////////////////////////////////////////////

    public function getTracks()
    {
        trace(“// getting tracks”)
        // create a pending call out to rails
        var pc:PendingCall = this.svc.getTracks();
        // create a responder to handle the return from rails
        pc.responder = new RelayResponder(this, “onGetTracks”, “handleRemotingError”);
    }

    public function onGetTracks (re:ResultEvent)
    {
        if (re != undefined)
        {
            trace(“// onGetTracks broadcaster - Word!”)
            // put result in recordset
            tracks = re.result;
            // trace for testing
            for (var i = 0; i < tracks.length; i++) {
                trace(tracks[i].title);
            }
            // dispatch event to the view
            dispatch(tracks, “onGetTracks”);
        }
    }
}

This is a little bit out of order but I’m going to show the ‘controller’ code next. The thing to notice is ‘Rmp3′ is an instance of my Extended Remoting class and it has two parameters the weborb gateway URL ‘http://localhost:3000/weborb‘ and the ruby class that’s in the app/services folder ‘TrackService‘. I haven’t shown the Extended View class yet bu the controller code is also creating a ‘Vmp3′ instance of it with the _root of the Flash file as it’s parameter (it uses that as a target). The next four lines are delegating button functions that are in the Extended View, the last line ‘Rmp3.getTracks();‘ calls the remoting method and is the entry point for the app (as it’s pretty useless sans data).

// import remoting, view, and debug
import mx.remoting.debug.NetDebug;
import mx.utils.Delegate;
import com.vixiom.remoting.RemotingMp3;
import com.vixiom.view.ViewMp3;

// ini debug
NetDebug.initialize ();

iniApp();

// setup and start
function iniApp()
{
    // create remoting & view objects
    var Rmp3:RemotingMp3    = new RemotingMp3 (“http://localhost:3000/weborb”, “TrackService”); // weborb gateway, ruby class name
    var Vmp3:ViewMp3        = new ViewMp3 (_root);

    // set up listeners
    Rmp3.addEventListener (“onGetTracks”, Delegate.create (Vmp3, Vmp3.onGetTracks));

    pause_btn.onRelease = Delegate.create(Vmp3, Vmp3.pauseTrack);
    play_btn.onRelease  = Delegate.create(Vmp3, Vmp3.playTrack);
    prev_btn.onRelease  = Delegate.create(Vmp3, Vmp3.previousTrack);
    next_btn.onRelease  = Delegate.create(Vmp3, Vmp3.nextTrack);

    // start the app, get the tracks
    Rmp3.getTracks();
}

Here’s the Extended View. It’s pretty complicated and unrelated to Rails or Remoting so I’ll just wave my hands and say "Ta da!", hopefully my comments explain what’s going on. Our tracks object from the remoting side hitches a ride on an event object in the listener ‘onGetTracks’ (tracks = eventObj.data;)

class com.vixiom.view.ViewMp3 extends com.vixiom.view.View
{
    // tracks holder object
    private var tracks              :Object;
    private var currentTrack        :MovieClip;
    private var albumArt            :MovieClip;

    // tracking vars (no pun intented)
    private var currentTrackNumber  :Number;
    private var totalTracks         :Number;
    private var pausePos            :Number;

    // song position interval
    private var songPosInterval     :Number

    //////////////////////////////////////////////////////////////////////
    //
    // Constructor (target)
    //
    //////////////////////////////////////////////////////////////////////

    public function ViewMp3 (t:MovieClip)
    {
        super(t);
    }

    //////////////////////////////////////////////////////////////////////
    //
    // onGetTracks listener
    //
    //////////////////////////////////////////////////////////////////////

    public function onGetTracks(eventObj:Object)
    {
        trace (“// onGetTracks listener - Word heard!”)
        tracks = eventObj.data;

        // keep track of total tracks :P
        totalTracks = tracks.length;

        // setup the mp3 player
        iniPlayer();
    }

    //////////////////////////////////////////////////////////////////////
    //
    // setup the player
    //
    //////////////////////////////////////////////////////////////////////

    public function iniPlayer ()
    {
        // local reference
        var vObj:ViewMp3 = this;

        // movieClip to hold the currently playing mp3
        target.createEmptyMovieClip (“currentTrack”, 1);
        currentTrack = target.currentTrack;

        // movieClip to hold album art, position it
        target.createEmptyMovieClip (“albumArt”, 2);
        albumArt = target.albumArt;
        albumArt._x = (Stage.width - 150) / 2;
        albumArt._y = 14;

        // display song position
        songPosInterval = setInterval (songPos, 50, vObj);

        // play first song (0 represents the first object in the Tracks object not an id in the database)
        loadTrack (0);
    }

    //////////////////////////////////////////////////////////////////////
    //
    // load a song into the player
    //
    //////////////////////////////////////////////////////////////////////

    public function loadTrack (t:Number)
    {
        trace(“// loading track: “ + tracks[t].title)

        // local reference
        var vObj:ViewMp3 = this;

        // keep track :P
        currentTrackNumber = t;

        // sound object for the current track
        currentTrack.soundObj = undefined;
        currentTrack.soundObj = new Sound ();

        // what to do when the sound loads
        currentTrack.soundObj.onLoad = function () {
            // don’t know if it’s a bug but sometimes songs don’t start at the beginning, make sure they do…
            currentTrack.soundObj.stop ();
            currentTrack.soundObj.start (0);
        };

        // what to do when the sound finished
        currentTrack.soundObj.onSoundComplete = function () {
            trace (“// complete”);
            // play next track
            vObj.nextTrack();
        };

        // load the mp3
        var mp3ToLoad = “http://localhost:3000/mp3/” + tracks[t].filename
        currentTrack.soundObj.loadSound (mp3ToLoad, true);

        // load album art
        var artToLoad = “http://localhost:3000/images/” + tracks[t].album_art
        albumArt.loadMovie(artToLoad)

        // display artist & track name
        target.artist_txt.text = tracks[t].artist
        target.title_txt.text = tracks[t].title
    }

    /////////////////////////////////////////////////////////////////////////
    //
    // Button Functions
    //
    /////////////////////////////////////////////////////////////////////////

    // pause
    public function pauseTrack()
    {
        trace(“// pause”);
        currentTrack.soundObj.stop ();
        pausePos = currentTrack.soundObj.position / 1000;
        trace (pausePos);
    }

    // play
    public function playTrack()
    {
        trace(“// play”);
        currentTrack.soundObj.start (pausePos);
    }

    // prev
    public function previousTrack()
    {
        trace(“// previous”);
        pausePos = 0;

        // set next song to play
        if (currentTrackNumber == 0) {
            currentTrackNumber = totalTracks - 1;
        } else {
            currentTrackNumber;
        }

        // play next track
        loadTrack (currentTrackNumber);
    }

    // next
    public function nextTrack()
    {
        trace(“// next”);
        pausePos = 0;

        // set next song to play
        if (currentTrackNumber != totalTracks - 1) {
            currentTrackNumber++;
        } else {
            currentTrackNumber = 0;
        }

        // play next song
        loadTrack (currentTrackNumber);
    }

    /////////////////////////////////////////////////////////////////////////
    //
    // Song Position
    //
    /////////////////////////////////////////////////////////////////////////

    public function songPos(vObj)
    {
        var time = vObj.currentTrack.soundObj.position / 1000;
        var duration = vObj.currentTrack.soundObj.duration / 1000;
        var elapsedTime = time / duration;
        var minutes = time / 60;
        var seconds = Math.floor (time % 60);
        if (seconds < 10) {
            var secOut = “0″ + seconds;
        } else {
            var secOut = seconds;
        }
        if (minutes < 1) {
            var minOut = “00″;
        } else {
            var min = Math.floor (minutes);
            if (min < 10) {
                minOut = “0″ + min;
            } else {
                minOut = min;
            }
        }
        vObj.target.time_txt.text = minOut + “:” + secOut;
        vObj.target.elapsed._xscale = elapsedTime * 100;
    }
}

That’s it! you now have a custom MP3 player that receives it’s data on the fly from Rails, and no cross browser testing! The one ‘cross’ item to watch out for is cross domain security but that only applies if your rails is on one server and your Flash file is on another.

This really just scratched the surface of what remoting can do, I haven’t even covered sending data from Flash to Rails, it’s just as easy (easier?) than working with Ajax in Rails. Actually it can do some things Ajax can’t (file uploads for one).

Digg! submit Flash Remoting for Rails Tutorial to stumbleupon.com submit Flash Remoting for Rails Tutorial to del.icio.us submit Flash Remoting for Rails Tutorial to reddit.com Like this post? subscribe to the feed.

29 Comments »

  1. Wow, great tutorial! I spent Tuesday evening scratching my head and trying figure out how to port WebOrb’s Flex tutorial to Flash remoting. This is a great help. Hopefully we’ll see another post on sending data from Flash back to Rails?

    Comment by Meekish — August 24, 2006 @ 10:29 am

  2. I was about to do a tutorial on passing data back to Rails but I hit an error I couln\’t figure out. I posted it to the Midnight Coders forum hopefully someone will have an answer. It\’s almost the same passing data as getting data you just add parameters to your pending call this.svc.updateTrackName(id, new_name); Rails can then use them in it\’s methods

    def updateTrackName(id, new_name)
    trackToUpdate = Track.find(id)
    tracToUpdate.name = new_name
    trackToUpdate.save
    end

    Comment by KreeK — August 25, 2006 @ 1:17 am

  3. […] In the first tutorial I showed how easy it is to pass data from Ruby on Rails to Flash via Flash Remoting, this tutorial will show how that sending data objects back to Rails is just as simple. Backpack was one of the first apps to get people excited by Rails. I’ll be ripping off their To-do list feature and making it Flash rather than Ajax. I’m using Flash professional DataGrids for this, so unfortunately if you only have the regular flavor of Flash you’re out of luck (I’m guessing if you do webdev with Flash you use the pro version anyways). The entire source code for the tutorial can be downloaded here. […]

    Pingback by Vixiom Axioms » Flash Remoting for Rails Tutorial 2 - Data Swings Both Ways — August 26, 2006 @ 3:03 pm

  4. […] Vixiom Axioms » Flash Remoting for Rails Tutorial […]

    Pingback by danielyuen.hk : Flash Remoting for Rails Tutorial — September 2, 2006 @ 10:20 pm

  5. Hi I download your example and and run the ruby script/server
    It successfully boot the Webrick server
    but how to invoke your mp3………
    I try http://localhost:3000/mp3 on browser but it display
    Recognition failed for “/mp3″

    and try http://localhost:3000/weborb
    but NoMethodError in WeborbController#index display….
    Help me to invoke the example…….
    thanks

    Comment by Raru — September 7, 2006 @ 4:16 am

  6. Hi,

    The Flash file will work just as an image would, it’s not dependent on a certain URL route. If you’ve tested it in the Flash IDE and it works you can export a .swf and use it anywhere on your website. Place the .swf file in the ‘app/public’, I use ‘app/public/swf’, then embed that .swf in any .html or .rhtml file on the site.

    thanks

    Comment by KreeK — September 7, 2006 @ 8:42 am

  7. Currently, when i develop on my machine, everything works great; however, when i upload to the server *http://www.blythe-band.com/audios* running off the weborb gateway, weborb fails to interact with anything (even the examples - http://www.blythe-band.com/examples/main.html). Any ideas? Is anything special required to run weborb on an apache server, like configuration of ports or mime-types?

    Comment by Brandon Martinez — September 7, 2006 @ 10:32 pm

  8. Hey Brandon,

    I was going to suggest posting to the Midnight Coders forum but I see that you already have. It’s odd that the examples don’t work online.

    What error are you getting in the production log (log/production.log)?

    It might be a flash security issue do you have a crossdomain.xml file in your rails root (/public/crossdomain.xml)? sometimes you need one even if the service you’re requesting is on the same domain as your flash file. Also put ‘System.security.allowDomain (”*.blythe-band.com”);’ before any remoting code in your flash file.

    You can also test your flash file locally but make calls out to the server instead, just change

    var Rmp3:RemotingMp3 = new RemotingMp3 (“http://localhost:3000/weborb”, “TrackService”);

    to

    var Rmp3:RemotingMp3 = new RemotingMp3 (”http://blythe-band.com/weborb”, “TrackService”);

    then you can use the NetConnection Debugger (in the flash IDE: Window>Other Panels>NetConnection Debugger) which might be able to give you some info into the error.

    good luck!

    Comment by KreeK — September 8, 2006 @ 12:30 am

  9. I do have the cross domain file, and i Add the System.security.allowDomain (”*.blythe-band.com”) before any remoting code; but nothing. No errors show up in the production.log, but I can retrieve data from the server if i look up the information locally. It’s just weborb that doesn’t work for some reason. The NetConnection Debugger shows me nothing, and the only thing the output window shows is Error connecting to… That’s it.

    Comment by Brandon Martinez — September 8, 2006 @ 5:34 am

  10. Great tutorial… I would love to see this integrated into the Ruby on Rails RIA SDK by Adobe (http://code.google.com/p/rubyonrails-ria-sdk-by-adobe/) that I’ve started with Derek Wischusen (http://www.flexonrails.net/).

    Contact me if you’d like to contribute this to that SDK.

    Mike

    Comment by Mike Potter — September 18, 2006 @ 6:41 am

  11. […] The kit features six examples - and growing - of Flex/Fash with Ruby on Rails goodness including my Flash Remoting with Rails MP3 player tutorial. Big Ups to Mike Potter of Adobe for setting up the SDK and allowing me to contribute to it. […]

    Pingback by Vixiom Axioms » The Ruby on Rails Rich Internet Application Software Development Kit by Adobe — October 5, 2006 @ 1:46 am


  12. pause_btn.onRelease = Delegate.create(Vmp3, Vmp3.pauseTrack);
    play_btn.onRelease = Delegate.create(Vmp3, Vmp3.playTrack);
    prev_btn.onRelease = Delegate.create(Vmp3, Vmp3.previousTrack);
    next_btn.onRelease = Delegate.create(Vmp3, Vmp3.nextTrack);

    That’s some clever code. I’ve never seen Delegate used that way…

    Perhaps that’s a fairly common usage and I’ve been living under a rock for the last couple of years?

    Comment by Meekish — January 1, 2007 @ 10:21 pm

  13. I ran into a similar problem as Brandon did where nothing seemed to happen at first. After looking through the log files I saw that a before_filter I had placed on the application controller was getting in the way of weborb processing the request. Adding a skip_before_filter :your_filter_name_here cleared everything up.

    Comment by Ryan Mohr — January 4, 2007 @ 8:25 pm

  14. You could express the essence of the remoting actionscript for the flash part thusly:

    import mx.remoting.Service;
    import mx.remoting.PendingCall;;
    import mx.rpc.RelayResponder;
    import mx.rpc.FaultEvent;
    import mx.rpc.ResultEvent;

    function onGetTracks(re:ResultEvent):Void {
    var tracks:Object = re.result;
    for (var i:Number = 0; i

    Comment by Justin Bishop — February 8, 2007 @ 12:48 am

  15. […] Vixiom Axioms » Flash Remoting for Rails Tutorial […]

    Pingback by Flash Remoting for Rails Tutorial - danielyuen.hk Blog — February 9, 2007 @ 10:08 am

  16. all of the code examples uses left anr right quotes. may look good but needs to be replaced when you put that in .as or .rb file :(
    great tutorial anyway

    Comment by michal — March 6, 2007 @ 6:00 am

  17. If you have trubles getting the onComplete function triger, make the upload server script response this

    &bError=0&

    In PHP:

    Comment by Rodrigo Polo — April 14, 2007 @ 9:26 pm

  18. I think it is good intentions but I find it a bit confusing and too complicated for my taste. It would be really more profitable to have a simple tutorial that could show just how retrive a list for ruby to rail. I sure you could do that for us :)

    I am still going to study you exemple. It is the only one, so you are kind of a good one !

    Thanks

    Comment by Gilles — May 25, 2007 @ 7:55 am

  19. do the mp3’s have to fully load before the player can start? can we see this in action? i am wondering if the same thing is possible with video. i have a need to bring raw video data in packets from the a client computer into a flash player and make it play the video as it downloads. is this possible with remoting?

    thansk for any help
    crabpot8

    Comment by crabpot8 — August 22, 2007 @ 7:31 pm

  20. The MP3’s start playing before they are fully loaded, however the MP3 files aren’t transfered via remoting but the playlist is. Remoting is an alternative to XML for data transfer, technically you could transfer video data packets but you’d have to build your own serializer. The best choice for streaming Flash video is the Flash Media Server (http://www.adobe.com/products/flashmediaserver/), there’s also an open source Flash media server called Red 5 (http://www.osflash.org/red5). Flash video files can also load over http but they would play progressively (you couldn’t jump further ahead in the video)

    Comment by Alastair — August 23, 2007 @ 9:24 am

  21. Can anybody tell me which version of actionscript is used ?

    Comment by Ron — September 6, 2007 @ 1:55 pm

  22. This example uses ActionScript 2, see this link for AS3 http://osflash.org/projects/ssr the Rails part is the same

    Comment by Alastair — September 6, 2007 @ 4:46 pm

  23. Just for documentation sake. RubyAMF is a great alternative to weborb. rubyamf.org -Aaron

    Comment by Aaron — September 18, 2007 @ 9:22 pm

  24. […] http://blog.vixiom.com/2006/08/23/flash-remoting-for-rails-tutorial/ […]

    Pingback by MaxUp Blog’s | » Links sobre Flex + Ruby On Rails — December 28, 2007 @ 8:35 am

  25. This is a great tutorial, thanks!

    Comment by Avery Lin — February 8, 2008 @ 9:27 pm

  26. hi…
    I’ve been working on the tutorial for a while and I still can’t get it to work.
    I already have flash remoting components installed. I downloaded the sourcecode for this tutorial. When I opened mp3player.swf with flash player, it doesn’t work. I click ‘fwd’ or ‘rev’ buttons on the player and it says ‘undefined’ :(.
    Another thing… when I go to http://localhost:3000/weborb from browser, it says “500 internal server error”.
    Any help please :(

    Thanks….

    Comment by coder — February 29, 2008 @ 2:38 am

  27. Hi I can’t get this to work. To debug the code, I implemented public function handleRemotingError(fault:FaultEvent) in RemotingMp3 and apparently, the function gets called after this line pc.responder = new RelayResponder(this, “onGetTracks”, “handleRemotingError”); is executed in getTrack().

    I really don’t know how to get this to work :(
    Please help me out.

    Comment by newbie — March 1, 2008 @ 2:59 pm

  28. Hello ,

    My previous seminar went well. Now I have an another query, if you help me in this also.
    As there is a concept of remoting in .net,
    is this possible to deploy the components in ROR and to make these components communicate with each other as done in remoting concept?
    Is this possible in ROR?
    Please guide me.

    Thanks
    Harbans

    Comment by harbans — May 8, 2008 @ 2:25 am

  29. […] Tutorials: Flexible Rails excerpt: Refactoring to RubyAMF,   Flash Remoting for Rails Tutorial […]

    Pingback by Flash The Ripper » Archives » Flex Remoting implementations for different platforms — August 7, 2008 @ 11:53 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

*
To prove you're a person (not a spam script), type the security word shown in the picture.
Anti-Spam Image

Powered by WordPress