Creating BlazeDS channels at runtime

Usually we create channels in services-config.xml and give URL to channel end points in the same file. This is good if the server IP or the domain name will not change. What if we are developing on our system and deploying to the production server? We need to change the end point URL in the services-config.xml and recompile our application.  It will be great if you can change the end point URL at one location and the Flex application will start using that URL without a need for recompiling the application.

Solution is simple you will have to create channels on runtime. This is very straight forward and easy. 🙂 You need not even add your services-config.xml to the compiler arguments.

I created a sample application which will access a XML file and then create the channels based on the settings in the configuration file.

XML configurations file with channel details

I created a XML file which has details of the channels which my application has to create. If you see the snippet extracted from the XML file it has definition for AMF channel. In the definition the id is the ID of the channel configured in the services-config.xml file on the server and the endpoint node has the URL to the end point.

Download XML from this URL: ChannelsConfiguration.xml

<ChannelsConfig>

<channels>

<channel id=”my-amf”>

<type>amf</type>

<endpoint>http://localhost:9191/lcdssamples/messagebroker/amf</endpoint&gt;

</channel>

</channels>

</ChannelsConfig>

Creating Flex application

Download MXML file from this URL: DynamicChannels.mxml

Now that I have a XML file with details of the channel my application will be using. I loaded this file when my application starts and create required channels so that my application can communicate with the server for using Remoting/Messaging/Proxy/Data management services provided by LCDS/BlazeDS.

Once the application is created function named loadConfiguration() is invoked which will make a HTTP Service request to get the XML file. Check out the function, it is pretty straightforward HTTP Service call.

When the XML is retrieved I parse the XML file and create channels in the parseConfigurationFile() function. Below are few statements extracted from the parseConfigurationFile() function which are worth explaining J

First I create a new channel.

_amfChannel = new AMFChannel(channel.@id, channel.endpoint);

Next add this channel to the ChannelSet.

amfChannelSet = new ChannelSet();

amfChannelSet.addChannel(_amfChannel);

That’s it we have created the channel sets which we will be using in the RemoteObject call later. I created more channels

Now that I have the channel sets I need to instruct my RemoteObject to use this channel sets when it is trying to communicate with the server. This is how you do it.

<mx:RemoteObject id=”rmObj” destination=”MySessionHandler”

channelSet=”{amfChannelSet}”

result=”resultHandler(event)”

fault=”faultHandler(event)”

showBusyCursor=”true”/>

That is all you need to do🙂 you can invoke operations on RemoteObject as usual. This applies to RemoteObject/Consumer/Producer/DataService🙂

18 Responses to Creating BlazeDS channels at runtime

  1. If you leave the tokens {server.name} and {server.port} in your endpoints there is no need to recompile your app since those 2 tokens are evaluated at runtime.
    It also prevents the application stoping working when people browse to http://mydomain.com instead of http://www.mydomain.com.

  2. Mete Atamel says:

    Note that you can also have custom tokens like {my.channel} in services-config and you can get those replaced by Java JVM options like -Dmy.channel=foo.

  3. Sujit Reddy G says:

    Hi Fernandes,

    Is it only the {server.name} and the {server.port} that are substituted or is {context.root} replaced too ???

    I tried to see if the tokens are evaluated at runtime and could not get it working completely. Looks like the server and the port tokens are substituted at runtime but not the context root token.

    This is what I did to check if the tokens are actually substituted at runtime.
    I created Flex project with mapping to BlazeDS deployment and got it working. Now i deployed the compiled SWF to another web application folder and launched it. If the tokens are evaluated at runtime, the send should fail as the URL i am launching from does not have the destination I am accessing. Right ? But the request is being sent to the correct web application in which I have my destination running.

    Please correct me if I am wrong.

  4. context-root is not evaluated at runtime, that’s why in Flex Builder you have that option to inform which context-root is your app supposed to be running.

    if the new webapp doesn’t contain the destination, of course it won’t work.

    With tokens, if you load your app from
    http://www.somedomain.com
    http://somedomain.com/
    http://somesubdomain.somedomain.com/
    http://somedomain.com/someFolder/deeperFolder

    as long your http://{putYourDomainHere}/messagebroker/ exists your app won’t fail. Of course if you move from one domain to another but the context-root from this new app changes, you’ll have to correct the endpoint,it’s trivial

  5. peter says:

    Hi,

    there is one problem with your solution, because you could not use the property settings from the services-config.xml, as example the polling-interval-seconds. Do you have an idea about this?

    MFG peter

  6. peter says:

    OK,

    I have found the necessary functions to set the polling-intervall, i set the definition with the applySettings method!

  7. Sujit Reddy G says:

    Hi Fernandes,

    Thank you very much for explaining clearly how it works.🙂

  8. Sujit Reddy G says:

    Hi peter,

    applySettings() function is also a good option🙂 You can try creating a JSP/Servlet which can access your services-config.xml and give only required details rather than exposing entire XML.
    In the sample above instead of URL to the XML directly you can point to the JSP/Servlet which will give an XML as output with required details from services-config.xml to create channels at runtime🙂

  9. kathy says:

    how will this example work if in the DynamicChannels.mxml you have to specify your own url which is hardcoded to be: http://localhost:9191/helloworld/ChannelsConfiguration.xml. What if you deploy the flexapp on a totally different machine with a different server, port and context root?

  10. Sujit Reddy G says:

    Hi Kathy,

    If you are deploying the Flex app in totally different machine, if you can manage to keep the .XML file accessible through the URL specified in the application this will work. This is might not be required for a web application, but imagine if you have an AIR application which was compiled with the end-point URLs which will have to change now !!! in that case if you can just make sure the .XML is accessible. We are reducing the dependency to one XML file rather than URLs of all the end-points. This is just my opinion🙂

    If you have better solutions, it will be great if you can share the same🙂

  11. 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.

  12. Sujit Reddy G says:

    Hi Vandana,

    Couple of things to consider. First check if the endpoint URLs in the services-config.xml are changed accordingly, so that the request is sent to the appropriate server. Changing the end-point URLs in the service-config.xml will require u to recompile (clean) your application.
    You will also need a crossdomain policy file on the server where your BlazeDS is hosted. Please find more details at this URL
    http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html

    Hope this helps.

  13. Param says:

    Mete / Sujit,

    I tried the custom token in the configuration file, services-config.xml. But the flex builder gives me the below error.

    Token ‘{cjleads.channel.class}’ in ‘services-config.xml’ was not replaced. Either supply a value to this token with a JVM option or remove it from the configuration.

    Because of which i am not able to compile my application. Any thoughts on how i can overcome this issue.

    Custom token suits my situation very well. But since i am getting compiler error i am not able to get the latest build of the movie file.

    Any pointer would be much appreciated.

    Thanks
    Param

  14. Param says:

    Hi..
    I found out how to add the new custom token.I need to edit the file, FlexBuilder.ini.

    But, The runtime values are not reflected. If i pass in a new value for those custom token as JVM arguments, those are *not* replaced by the application.

    But if i didn’t specify those arguments i got the exception.

    So, The BlazeDS Configuration is looking for those custom token value to be passed as JVM arguments, but those values are not updated.

    If anyone know how to fix this issue let me know.

    Thanks
    Param

  15. Jasbir Singh says:

    Hi,
    I have a requirement where i need to decide at runtime whether to hit secure amf or non secure amf. After reading above discussions this is clear that we can provide channels at runtime while creating a remote object .But in my case we are picking all remote objects from configuration file(i.e flex-remoting.xml).

    Can you please give some inputs on how to provide secure/non-secure amf at runtime specially when we are getting all the remote objects from configuration file.

  16. Hi Jasbir,

    Please check the endpoint property of the RemoteObject.

    Hope this helps.

  17. Flexdeveloper says:

    Hi,
    can you please let me know how can i deploy same build to my multiple environments (dev/sit/uat/prod), i’m following here a concept of build once and deploy multiple times., i don’t want to compile application again for deployment i do for each environment, for my each environment (dev/sit/uat/prod) server name and server port will change. as you mentioned have other xml file, but there also somebody has to manually change url and port.
    Thanks in advnace.

  18. Hi FlexDeveloper,

    I guess using ANT scripts is the best option. Please check this article http://www.adobe.com/devnet/flex/articles/flex_ant_pt1.html

    Hope this helps.

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

%d bloggers like this: