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