Announcement Announcement Module
Collapse
No announcement yet.
A note on defining ChannelSets with Spring BlazeDS Integration Page Title Module
Move Remove Collapse
This is a sticky topic.
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • A note on defining ChannelSets with Spring BlazeDS Integration

    The issue of having to configure ChannelSet definitions in the Flex client in order to properly communicate with the Spring BlazeDS Integration configured remoting destinations has come up several times now, so I wanted to provide some clarification for reference until such time that we can add something similar to the project documentation.

    As I've mentioned before, explicit channel definition is a requirement when using dynamic destinations (meaning any destination that is added programmatically and not defined in the BlazeDS services-config.xml, i.e. the destinations created by the FlexRemotingServiceExporter):
    http://livedocs.adobe.com/blazeds/1/..._5.html#194376

    The only way you don't have to explicitly define the ChannelSet on the client is if
    a) you are using explicitly defined destinations in services-config.xml (i.e, not dynamic destinations) AND you compile your flex client against that file
    OR
    b) your destination is using the application-wide default channel AND you compile your flex client against that file

    Even if you weren't using dynamically created destinations it is debatable whether it is a good idea to ever compile your client against services-config.xml, thus coupling your client to your server configuration. It is often desirable to keep your flex client and your server side code as two distinct modules, but compiling against services-config.xml blurs the lines between those modules.

    I personally feel it is cleaner to keep the client-side configuration of ChannelSets explicitly contained within the client module. An excellent way to do this without having to hard-code the URLs in your client code is to use an ActionScript DI framework such as Spring Actionscript (formerly known as Prana).

    A nice step-by-step example of using Spring ActionScript for this can be found here:
    http://forum.springsource.org/showthread.php?t=95754

    If you choose to go the route of compiling your client against services-config.xml, note that you can at least keep the URL information out of the client code by using ServerConfig.getChannel as described in the referenced BlazeDS documentation.
    Last edited by jeremyg484; Oct 1st, 2010, 12:59 PM.

  • #2
    To add to this, there is a blog post available at http://www.herrodius.com/blog/158 that shows an example of a Spring ActionScript configuration for ChannelSet, Consumer and RemoteObject.

    In addition we also added support for using application properties. These properties are runtime info of the application and contain the url and other properties. The ApplicationPropertiesResolver enables you to use magic properties in your context or properties file that get replaced by application properties.

    A typical use case is that you'll want to have a predefined host and port in your properties file when developing. When you need to deploy, you can then replace these by the available application properties so it's easier to deploy on several machines or set up virtual ip's.

    Here's an example (based on the examples in the blog post):

    Code:
    // in a properties file
    host=${application.url.host}
    port=${application.url.port}
    ... and add the application properties resolver in the context:

    Code:
    <!--  Object factory post processor to resolve application properties -->
    <object class="org.springextensions.actionscript.ioc.factory.config.flex.ApplicationPropertiesResolver"/>
    This code has not been released yet but is available in SVN.

    regards,
    Christophe

    Comment


    • #3
      Having an issue with the following setup:

      Flex--><--VIP--><--blazeds-->tomcat

      We have 2 machines in the VIP, and all flex code is buddied with the WAR deployment.

      If I hit one of the machines in the VIP directly I have no issues. If I hit the VIP then I get a "Channel Disconnected" error <b>on the response message only</b>. Also this appears to be related to the size of the response message. Small response messages (customer list of less than 100) works fine; whereas larger response messages (customer list of more than 600) yields the "Channel Disconnected" error.

      I checked the logs and there are no errors being printed out by either the backend java stack or the blazeds framework. This appears to all be failing within the flash player while consuming a <b>large response</b> message <b>through a VIP</b>.

      Can anyone here lend a hand?

      Comment


      • #4
        Example of the definition of an application-wide default channel in services-config

        The BlazeDS Integration documentation (as of 1.0.3) encourages the decoupling of the BlazeDS channel configuration in the client from the channel config in the server. While in many cases this is the right thing to do, in other cases developers may prefer to define the configuration in one place (in services-config.xml) and compile the client(s) against service-config. Developers using the joint Java-Flex project support in Flash Builder, for example, (provided under the hood by Eclipse WTP) will find this approach convenient, especially in the early stages as they are learning the framework.

        Unfortunately neither the BlazeDS Integration documentation (as of 1.0.3) nor Adobe's LCDS documentation (as of 3.0) provides an example of how to define an application-wide default channel set in services-config.xml.

        You can define a default application-wide channel in service-config.xml as follows:-
        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        <services-config>
        
            <services>
                <default-channels>
                    <channel ref="longpollamf"/>
                </default-channels>
            </services>
        	
            <channels>
                <channel-definition id="longpollamf" class="mx.messaging.channels.AMFChannel">
                    <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/longpollamf" class="flex.messaging.endpoints.AMFEndpoint"/>
                    <properties.... />
                </channel-definition>
            </channels>
        
        </services-config>
        With an application-wide default channel set in services-config you can define mx:RemoteObjects, mx:Producers and mc:Consumers in the client as follows without having to specify a channel configuration explicitly. (This assumes the client is compiled against service-config.xml which has been the default in Flex/Flash Builder for projects set up with BlazeDS support since WTP support was introduced in v2.0.1).

        Code:
        	<mx:Consumer id="notificationConsumer" destination="notification" />
        and allows a simpler Spring config as follows:-

        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
        	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        	xmlns:flex="http://www.springframework.org/schema/flex"
        	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        		http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">
            
            <flex:message-broker>
                <flex:remoting-service />
                <flex:message-service />
            </flex:message-broker>
        	 
            <flex:message-destination id="notification" />
        	
            <bean id="notificationServiceMessageTemplate" class="org.springframework.flex.messaging.MessageTemplate"/>
        
        </beans>
        Additionally remoting endpoints annotated as Spring BlazeDS endpoints work too without having to specify a channel explicitly as follows:

        Code:
        @Service
        @RemotingDestination
        public class TradeService 
        {
            ....
        }
        I think the section in the BlazeDS Integration documentation that discusses this topic would be better with an example of configuring an application-wide default channel set in service-config (even if you choose to discourage its use) as it significantly reduces the complexity of the Spring BlazeDS config in the simple case.

        Comment


        • #5
          Sparky,

          Thank you so much for your explanation. This really helped me, I fit the profile you describe perfectly: new to the framework. I still fail to see the benefits on having the channels defined on the client side, and I dont want to add Prana to the picture. This would feel too much like Voodo Programming at the moment.

          Just as a quick tip, when using annotations, define your @Service like this

          Code:
          @Service("TradeService")
          @RemotingDestination
          public class TradeService 
          {
              ....
          }

          Else your Destination won't work. (at least this was my case).


          Again thanks a million,



          Alejandro
          Last edited by alexrrr; Jul 23rd, 2010, 01:38 PM.

          Comment

          Working...
          X