I just deployed a Flex app to an SSL secured host, and ran into some issues getting AMF over SSL working. Googling turned up the answers, but in rather fragmented form. So I'm coalescing them here. In a nutshell, you have to create a new channel (my-secure-amf) that uses the secured versions of the AMF classes (both AS and Java), and then register it as a usable channel for the ColdFusion destination. Here's a diff from my services-config.xml (in /WEB-INF/flex) with the four important bits bolded:
--- services-config.xml 2007-09-01 00:37:25.000000000 -0700
+++ services-config.xml 2007-09-01 00:59:41.000000000 -0700
@@ -13,6 +13,7 @@
<destination id="ColdFusion">
<channels>
<channel ref="my-cfamf"/>
+ <channel ref="my-secure-cfamf"/>
</channels>
<properties>
<source>*</source>
@@ -48,6 +49,15 @@
</serialization>
</properties>
</channel-definition>
+ <channel-definition id="my-secure-cfamf" class="mx.messaging.channels.SecureAMFChannel">
+ <endpoint uri="https://{server.name}:{server.port}{context.root}/flex2gateway/" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
+ <properties>
+ <polling-enabled>false</polling-enabled>
+ <serialization>
+ <instantiate-types>false</instantiate-types>
+ </serialization>
+ </properties>
+ </channel-definition>
</channels>
<logging>
In addition to this server-side config, you need to ensure your client connects to the proper channel and with the proper Channel (the AS class) implementation. If you're using services-config.xml in your compilation process, it's a no brainer, but if you're manually configuring your ChannelSet in code (parameterized, of course), you have to watch out. If you want to do the latter, here's how I do it:
private function configRemoteObject(gateway:String, cfc:String, useSsl:Boolean):RemoteObject {
var cs:ChannelSet = new ChannelSet();
if (useSsl) {
cs.addChannel(new SecureAMFChannel("my-secure-cfamf", gateway));
} else {
cs.addChannel(new AMFChannel("my-cfamf", gateway));
}
var ro:RemoteObject = new RemoteObject();
ro.destination = "ColdFusion";
ro.channelSet = cs;
ro.source = cfc;
ro.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void {
if (event.token.hasOwnProperty("resultHandler")) {
event.token.resultHandler(event);
} else {
trace("result event with no resultHandler: " + event);
}
});
ro.addEventListener(FaultEvent.FAULT, function(event:FaultEvent):void {
if (event.token.hasOwnProperty("faultHandler")) {
event.token.faultHandler(event);
} else {
trace("FaultEvent: " + event.fault.message);
}
});
return ro;
}
The three arguments to the method are pulled in via a URLLoader to an XML file such as the one below that is part of the deployment configuration (i.e. not part of the codebase).
<?xml version="1.0" encoding="utf-8"?> <settings> <gateway>/flex2gateway/</gateway> <useSsl>false</useSsl> <cfc>sorter.cfcs.count_facade</cfc> </settings>
I don't claim that this is the best way, but it does let you easily change where your SWF connects to without recompilation, which therefore lets you build your Flex projects standalone (no compile-time server linkage). Quite useful if you have a variety of environments you want a single project/SWF to work in.