Specifying an endpoint for a RemoteObject destination at runtime

When you intend to use BlazeDS or LCDS in your App, you usually start a new project in FlexBuilder and set the Server Technology to LCDS and then Set the Root folder and Context root and validate the configuration to create the project as below.

At this point, FlexBuilder adds a -services option to the compiler and sets it to the services-config.xml where the end-points for the services are set.

You can then write code as below where the destination is now configured in the config file that’s set at the location in -services option.

<mx:RemoteObject id=”artJava” destination=”ArtGallery” fault=”errorHandler(event)” showBusyCursor=”true”>
<mx:method name=”getArts” result=”onArtResult(event)”/>
</mx:RemoteObject>

If you look into the services-config.xml you will see the following lines there

<channel-definition id=”my-amf” class=”mx.messaging.channels.AMFChannel”>
<endpoint url=”http://{server.name}:{server.port}/{context.root}/messagebroker/amf” class=”flex.messaging.endpoints.AMFEndpoint”/>
<properties>
<polling-enabled>false</polling-enabled>
</properties>
</channel-definition>

When you run the app in FlexBuilder, it substitues the {server.name} and other variables from the configuation that you set when you created a new project and compiles this into the application. This works like a charm, but this has a problem.

Yesterday, I did an application and bundled it into a war file and send it to my friend. But when he ran it, it did not work. This was because, I had my BlazeDS installed on port 8400 while he had it on port 8080. Since my Builder had substituted the {server.name} at compile time, the only option was to give him the whole project and get him to recompile it for his configuration.

Thanks to Sujit, I discovered that you can not go this way and make this generalized by injecting these values at runtime, rather that these being at compiletime.

The trick is to create your own channel set and override the one that is there by default. Here’s how you achieve this..

  1. Create a new Project, but this time with the App Server type as none
  2. Create a ChannelSet and add an AMFChannel (which is used by the RemoteObject)

    var _channelSet:ChannelSet = new ChannelSet();
    var _amfChannel:AMFChannel = new AMFChannel(“my-amf”,            serverPath.text+”/[context-root]/messagebroker/amf”);
    _channelSet.addChannel(_amfChannel);

  3. Set the [context-root] appropriately and you will see above serverPath.text which is the input from a TextInput on which the user can now specify “http:\\localhost:8400″, “http:\\localhost:8080″ …etc
  4. Now create a RemoteObject and add this Channel set to it..

    javaClass = new RemoteObject(“myDataSource”);
    javaClass.channelSet = _channelSet;
    javaClass.addEventListener(ResultEvent.RESULT, onResult);
    javaClass.addEventListener(FaultEvent.FAULT, onFault);
    javaClass.getNSData();

  5. myDataSource is the destination configured in the remote-config.xml file.
  6. You are ready to fly :)

Now you app will work no matter the installation. Instead of inputting from a TextInput, in a complex app, it is better you read from a config file that you can add along with your app like Christophe has done with the SalesBuilder App.

9 Responses to Specifying an endpoint for a RemoteObject destination at runtime

  1. Bruce says:

    Thanks, Raghu, for the great article! We’re adding BlazeDS support for the FlowUI framework and this was just what we needed. Keep up the good work!

  2. priyank says:

    Nice post, a channel set is very handy. If you want to get data from different sources you can have more than one endpoints specified and it would get the result. AS3 + Flex is cool.

  3. Vlad says:

    Thanks a lot! this post helps me a lot in my project (it requires dynamic server urls)

  4. Emil Tamas says:

    Excellent… this was the only bottleneck we had in making an automated deployment..we always had to compile for *that* specific server and so on…

  5. Mark says:

    Thanks, I think this should help with my WebOrb installation as well. Quick question… if I have my WebOrb installtion (or in this case Live Cycle), what should go in the root folder box under server location?

    I want to develop the flex app on a different machine to the server – is this possible?

  6. Shakti says:

    Hi

    Your blog was very useful for us to understand how to use dynamic channel set.
    When run from Flex builder, it runs fine. I copied the bin-debug folder to wamp server and tried to run it from there. It gives ‘send failed’ error.
    In the LCDS window, it shows crossdomain.xml is found. I copied crossdomain.xml to lcds/jrun4/servers/default/samples/ but no success.
    Any suggestions as to how to solve this problem are welcome…

    -radha

  7. Vandana says:

    Hi,

    I am trying RemoteObject endpoint example.
    I run the application from Tomcat server & the endpoint points to Jboss server. When both Tomcat & Jboss is running on the same machine, it works perfectly.
    My swf file from tomcat server calls the remote object residing on jboss server.

    But If I try to access one of the servers in different machine It Gives Send Failed.

    For Ex:

    http://3.209.101.248:8400/TestDS/TestDS-debug/TestDS.swf

    swf File in Tomact is able to communicate
    endpoint=”http://3.209.101.248:8080/TestDS/messagebroker/amf”
    This works perfectly when both servers are running in same machine.

    But If one server say Jboss is running on another machine then It gives Error Send Failed.
    endpoint=”http://3.209.101.99:8080/TestDS/messagebroker/amf”

    What I need to do. Pls help me.

  8. drg says:

    Awesome article! I have a quick somewhat-related question about actually getting access to the default channels in place, instead of overriding the entire ChannelSet.

    From what I understand, each RPC has a ChannelSet which is a set of channels that the RPC uses to connect and relay messages back and forth. I have looked at the API docs and we have access to the ChannelSet from the RPC object. However, the ChannelSet does not give us direct access to the channels in it. Instead, it only contains an array of Channel Ids. I want to get direct access to all the Channels in a ChannelSet for a particular RPC – is there a way I could go about doing that? Is there a way to get access to a Channel given its id?

    Thanks, Raghu!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.