FlashComGuru Home InfluxisCDNImediaseeUvault
                                                                                       Forum Index | Active Topics | Register
                                                                                                          List Overview | List Archives
                                                                                                                           About this site | Advertise
 

home

Adobe AIR (11)
Applications (40)
Books & Training (11)
Collaboration (18)
Components (10)
Events (80)
Flash Player (35)
Flex (39)
FMS (110)
General (123)
Hosting (6)
Jobs (17)
Off topic (36)
OSMF (3)
Press Releases (23)
Site Check (11)
Tools (53)
Videos & Players (74)

Follow me on Twitter

 
I know (or want to believe) that this is actually quite easy... it must be. Here's the deal: I want to access an existing ColdFusions component (CFC) from inside a Flex2 app. I'm experienced with Flash Remoting and can call my CFCs just fine from Flash.
Now I'd like to port things to Flex2 but I am having trouble understanding some concepts. I went ahead and installed Flex2, Flex Data Services (FDS) and ColdFusion 7.0.2 on my laptop. First problem: I didn't understand if Flex Data Services was needed or not... I thought ColdFusion 7.0.2 provided some sort of Remoting gateway for flex2 yet this part of the Flex2 docs seems to suggest that RemoteObject can only be used with FDS - I know now that this does not seem to be the case as I managed to call a CFC on my local CF server using RemoteObject without FDS running. So what am I missing? Is the RemoteObject class different from the MXML tag that I am using? And if it isn't then why do the docs suggest 'FDS only'?
Here's the MXML snippet that works fine for me locally using Flex2 and CF 7.0.2 (no FDS running):

<mx:RemoteObject id="RO" destination="ColdFusion"
fault="Alert.show(event.fault.message), 'Error'"
result="Alert.show(String(event.result)), 'Result'"
source="names">

<mx:method name="getname">
</mx:method>
</mx:RemoteObject>

I gather that the destination 'ColdFusion' is somehow configured in Flex's services-config.xml - how and why I haven't yet grasped. The 'names' in my RemoteObject tag is the CFC on my local machine and the getname is hte method in the CFc that I call. This works fine, no problem. But I don't understand how I would access a remote CFC using this code... Do I have to edit XML files and create a destination for every site that uses Remoting? That sounds a bit crazy and the XML config scared me a bit...


So what I tried (to access the same CFC but this time on a remote CF box running CF 7.0.2) was to set an endpoint in my RemoteObject tag, pointing to my FlashRemoting gateway. Is that one way of achieving what I want or am I barking up the wrong tree?

Here's what I tried:

<mx:RemoteObject id="RO"
    endpoint="http://web.okaygo.co.uk/flashservices/gateway"
fault="Alert.show(event.fault.message), 'Error'"
result="Alert.show(String(event.result)), 'Result'"
source="cfc.flex" >

<mx:method name="getname">
</mx:method>
</mx:RemoteObject>

But all I got in Flex was this error:
TypeError: Error #1034: Type Coercion failed: cannot convert Object@9373841 to mx.messaging.messages.ErrorMessage.

I didn't quite understand this error as the method should return a string - but it was clear that it was throwing an error.
Try this link to see the CFC working in a browser (it should return the string stoem).

Please somebody, anybody, help! What I want to do is access a remote CFC with minimum fuss from Flex, ideally just using a RemoteObject MXML tag. Is that possible and if so, how? I'm trying hard to find the R in RAD here. I think the whole Flex Remoting/FDS/CF thing is really tough to grasp, even for someone who's familiar with Remoting.

Related Articles

Comments
[Add Comment]
You do not need FDS to do a simple remoting call to a cfc. Have you mapped an AS class to the component? I suggest Forta's article for a simple demo. http://www.adobe.com/devnet/flex/articles/coldfusi...
# Posted By todd sharp | 11/11/06 9:49 PM
This RemoteObject should work. The trick is the path to the CFC in the source. If your CFC is located here:

http://mydomain/cfc/flex.cfc

Then this RemoteObject Tag should work.

<mx:RemoteObject
id="RO"
destination="ColdFusion"
source="cfc.flex"
fault="Alert.show( event.fault.message ), 'Error'"
result="Alert.show( String( event.result ) ), 'Result'"
>
<mx:method name="getname"/>
</mx:RemoteObject>

Stefan, Before you pull your hair out send me an email at tpatrick@adobe.com. Glad to see you Flexing! Keep going, it takes time.

Cheers,

Ted :)
# Posted By Ted Patrick | 11/11/06 10:37 PM
is names (or ted's "CFC") a cf mapped dir? if so, then you have to turn on "use-mappings" bit in services-config.xml. otherwise your CFCs have to be web accessible.
# Posted By PaulH | 11/12/06 2:34 AM
thabks for all the replies. First off: no, names is not a mapped directory, it's the name of my cfc: names.cfc. In the working example (running CF and my flex app locally) names.cfc and RemoteObject works fine.
But how and where do I tell Flex that I want to use the REMOTE CFC at http://web.okaygo.co.uk/cfc/flex.cfc ?
Do I need to modify the xml config file for that? It just isn't clear to me.

To recap: I want to run my Flex app on my local machien and access a remote CFC (and its methods) at http://web.okaygo.co.uk/cfc/flex.cfc

Ted, your example looks like it will work but only if I upload my compiled swf to mydomain.com. Otherwise how would the app know which URL's remoting gateway I want to use? I know all about CFC paths, I use remoting in Flash all day long. But in Flash I connect to the gateway and then call methods on my CFCs - in Flex I don't see (using your example) any mention of mydomain.com so how would Flex know which gateway to use? It looks like a relative path to me and I don't want that, I want to explicitly use a remoting gateway at web.okaygo.co.uk (the Flash Remoting gateway is web.okaygo.co.uk/flashservices/gateway).

I guess I don't even understand yet if Flex and Flash share the same remoting implementation.

thanks for any pointers

Stefan
# Posted By Stefan | 11/12/06 4:01 PM
I think I understand now that there are 2 gateways, one at /flex2gateway and one at /flashservices/gateway.
The 'ColdFusion' destination as specified in Ted's example would be originating from the services-config.xml file with destination id="ColdFusion" which in turn refers to a channel my-cfamf which in turn specifies an endpoint that ends with /flex2gateway

This seems to be the gateway/URL that is used in mu local example. But I have to understand how I can specify another gateway, in particular the one at my remote site which is http://web.okaygo.co.uk/flex2gateway

Is the Flash Remoting gateway at web.okaygo.co.uk/flashservices/gateway useless in Flex?

Do I really need to mess with these scary looking XML files when I want to use Remoting on a remote server (which is what I need to do all the time)? Is this XML file being compiled into my Flex application? Is there another way to configure this? What would the XML look like in order to set up another Remoting location at web.okaygo.co.uk/flex2gateway ?

thx
# Posted By Stefan | 11/12/06 5:31 PM
what i meant was "CFC". is that a mapped dir or a web accessible dir?

i don't recall doing anything beyond setting the mapped dir option on (we have a lot of mapped cfc dirs). it just worked.
# Posted By PaulH | 11/12/06 6:01 PM
thanks Paul. CFC is a web accessible directory, not a mapping.
I didn't have to configure anything either to get remoting working via my LOCAL CF install - but how do I use a REMOTE remoting gateway? The server I use is web.okaygo.co.uk and it runs CF 7.0.2. How do I tell Flex that that's the gateway I want to use as that's where my CFCs live - they do not live locally.
# Posted By Stefan | 11/12/06 7:13 PM
Ok I got it working!

<mx:Application
   xmlns:mx="http://www.adobe.com/2006/mxml"
   creationComplete="ro.getData()"
   layout="absolute">
   
   <mx:RemoteObject
      id="ro"
      destination="ColdFusion"
      source="api.search"
      endpoint="http://www.flex.org/flex2gateway/">
      <mx:method name="getData"/>
   </mx:RemoteObject>
   
   <mx:DataGrid dataProvider="{ro.getData.lastResult}" left="0" top="0" bottom="0" right="0"/>

</mx:Application>


There are several keys:

1. You need a crossdomain.xml file located here:
http://www.flex.org/crossdomain.xml configured to allow connection from the other domain or in this case "*" (All)

2. You need to add the 'endpoint' property to the RemoteObject to denote the gateway implicitly with an HTTP URL.

This was a pain! I will make sure to blog this one.

Ted :)
# Posted By Ted Patrick | 11/12/06 10:46 PM
Thanks for the example Ted. I can't get it to work though but maybe it's not a live example.

What I still do not understand is why I need to specify a desination AND and endpoint:
   <mx:RemoteObject
      id="ro"
      destination="ColdFusion"
      source="api.search"      endpoint="http://www.flex.org/flex2gateway/">
      <mx:method name="getData"/>
   </mx:RemoteObject>

The docs state: "This property allows the developer to quickly specify an endpoint for a RemoteObject destination without referring to a services configuration file at compile time or programmatically creating a ChannelSet. It also overrides an existing ChannelSet if one has been set for the RemoteObject service."

But if I also need a destination then I am again referring back to the XML config file - which defeats the objective of being able to do everything in MXML.

I see the benefit of having the XML files but I want to understand how I can work without them. It seems strange to me that I would have to configure XML files on a local CF server in order to get flex to work with a remoting gateway on a REMOTE CF server...

I had some success myself. I created a simple XML config file and changed the endpoint ion XML to <endpoint uri="http://web.okaygo.co.uk/flex2gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>

I then included this XML file (which is inside my Flex project directory) via the comoiler command line. That worked fine with this code then:

   
   <mx:Script>
      <![CDATA[
         import flash.events.*;
         import mx.controls.Alert;
         
         private function init ():void
         {         
            RO.getmyname();
         }

      ]]>
   </mx:Script>
   
   <mx:RemoteObject
   id="RO"
   source="cfc.flex"
   destination="ColdFusion"
   fault="Alert.show( event.fault.message ), 'Error'"
   result="Alert.show( String( event.result ) ), 'Result'"
   />

It still means I must use a destination. Trying to rename the destination name in XML as well as MXML also broke my app.
# Posted By Stefan | 11/13/06 9:09 AM
BTW Ted, I had the crossdomain file in place the entire time.
# Posted By Stefan | 11/13/06 9:10 AM
another observation:

Ted's Flex remoting gateway seems to accept both syntaxes http://www.flex.org/flex2gateway/ and http://www.flex.org/flex2gateway and both work fine. I wonder why on my server it seems to require a trailing slash.
http://web.okaygo.co.uk/flex2gateway throws an error, http://web.okaygo.co.uk/flex2gateway/ works fine.

I am using IIS and not CF's built in webserver - could that have anything to do with it?
# Posted By Stefan | 11/13/06 9:22 AM
Maybe I have figured it out... Ted, what exactly does the destination argument do in your code? Does it actually refer to a destination in XML or is it just some sort of hint to tell RO that this is a CF gateway?
In any case, I modified my example and removed all compiler commandline options, meaning no XML files are being compiled into the Flex app anymore.
If I then run this code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">
      
   <mx:Script>
      <![CDATA[
         import flash.events.*;
         import mx.controls.Alert;
         
         private function init ():void
         {         
            RO.getname();
         }   
                     
      ]]>
   </mx:Script>
   
   <mx:RemoteObject
   id="RO"
   destination="ColdFusion"
   endpoint="http://web.okaygo.co.uk/flex2gateway/"
   source="cfc.flex"
   fault="Alert.show( event.fault.message ), 'Error'"
   result="Alert.show( String( event.result ) ), 'Result'"
   />
      
</mx:Application>

the app still works! I think this is what I wanted. But it seems to conflict with the docs on destination:
"The destination of the service. This value should match a destination entry in the services-config.xml file."
Well in my case it doesn't do that, I actually renamed my services-config file just to make sure that flex isn't somehow grabbing it anyway. My Remoting call still works now with no external configuration - great.

I hope we can continue to dig at this as there's still some loose ends that I don't quite understand.
# Posted By Stefan | 11/13/06 9:33 AM
You guys have fun. I changed all my Flex 2 remoting to webservices out of frustration and reused the cfc's as wsdl.
# Posted By Brad | 11/13/06 5:38 PM
lol Brad.
That's cheating though :-) Please reconsider - Remoting in Flex DOES work and is more efficient than SOAP.
While I can get Remoting to work ok now both locally and remotely I still haven't grasped the whole setup and concepts yet.
I'll try Aactionscript based Remoting next in a pure AS3 class and see how that fits in... Oh joy.
# Posted By Stefan | 11/13/06 7:16 PM
It was the lesser of two evils. Trying to get my network admin's involved in configuring our CF server is like an act of biblical proportion. That and we have this really weird proprietary CF knock-off language on all of our webservers serving up the Flex apps. The whole cross-domain thing was a nightmare in itself.
# Posted By Brad | 11/13/06 9:03 PM
I feel for you.
Spare a moment for myself too... I'm just messing with an AS3 class in Flex2 and I get a NetConnection.Call.BadVersion Error when trying to call a CFC method... I tried both AMF0 and AMF3 and both returned the same error. I start to get the idea as to why you gave up man...!
# Posted By Stefan | 11/13/06 9:19 PM
Stefan,

The 'destination' is the name used within the remoting calls to locate resources. Basically there are 2 parts to a remoting address:

1. Endpoint - Denotes the URL of the gateway. The default is /flex2gateway/ on the server the SWF is running on. If you want to point to a remote server running remoting, you change this to a HTTP or HTTPS url.

2. Destination - When the gateway receives a call it needs to be routed to the right resources. This destination is denoted on the target server you are calling. In the CF case, it is configured within the CF server. With FDS, it is configured within the FDS server config xml files (hence the docs). When using Coldfusion, the default to use is: 'ColdFusion'

I think that should get you square. Sorry about the trouble on this.

Have faith Flex gets easier once you get the hang of it. You are going well!

Cheers,

Ted :)
# Posted By Ted Patrick | 11/14/06 10:10 PM
Ok, I could use a little cluing in as well. I think my set up is a little similar as to yours Stefan. I have a laptop that I'm developing on and a dev server on my network, so no local install of CF. My problem is when I create a new Flex 2 project when I select "Coldfusion Flash Remoting Services" I have no clue what to put in the root folder field. Do I need to map a network drive to the WEB-INF/flex folder on the server?

One other question, I was going to install the ColdFusion Extensions for Flex (BuilderColdFusion_Flexbuilder_Feature.zip) but I can't seem to find it on my CF install on OS X. Know where this zip file is under OS X install?
# Posted By Mike Weiland | 11/15/06 2:43 AM
@Ted: thanks, I think I get it. What confused me greatly was the fact that I needed to set a destination for the RO and I thought this would refer to the XML config. Sounds like it's just a hint to Flex that this is CF Remoting. Thanks, this works for me, much clearer now.

@Mike: I think you should try and use a normal Flex project (not Remoting) and then simply use a similar approach to me where you tell the RO directly where your endpoint is. Also set the destination to ColdFusion and you should be ok.
Sorry no idea on the Extensions...
# Posted By Stefan | 11/15/06 9:27 AM
So how in the world do i set an endpoint in Actionscript 3? here is my code for the service, but i would like my CFCs to be located somewhere other than the wwwroot. I don't have access to the wwwroot and had to have it mapped in IIS just to create the project.

var ro:RemoteObject = new RemoteObject();
               
                ro.destination = "ColdFusion";
                ro.source = "getCCService";
               
                ro.getCCInfo.addEventListener("result",getTest_result);
                ro.getCCInfo.addEventListener("fault",somethingWentWrong);
   
                ro.getCCInfo();
# Posted By Dom | 12/18/06 6:02 PM
I'm not sure if I've tried this but usually CFC paths are specified using dot notation from the root:
folde.subfolder.mycfc

Maybe give that a shot.
# Posted By Stefan | 12/18/06 6:48 PM
Right, that is correct but my sites are hosted by IIS on a completely different drive. I had to map the coldfusion wwwroot just to setup the project. There are no subfolders in the wwwroot. Im thinking i have to create an endpoint to where i want to load my CFCs from. But i dont know how to create an endpoint in AS3 as there is no option to do that in the remote objects in AS3, only MXML.. oddly enough
# Posted By Dom | 12/18/06 6:53 PM
now I'm confused. The CF root shouldn't matter - you're not using CF's webserver, right? In a normal install under IIS, every CF site has its root in the website root - where IIS specifies it.
Sorry, maybe I am not understanding your exact setup and it may be easier to test this under 'normal' circumstances, without the additional complexity of this particular config.
# Posted By Stefan | 12/18/06 7:02 PM
Correct, im using IIS 6.
Coldfusion is installed on the C:\CFusionMX7\ drive.
The web content is installed on the E:\inetpub\wwwroot\ drive.

the CFC component getCCService is right now located in C:\CFusionMX7\wwwroot\ and it is working.
# Posted By Dom | 12/18/06 7:22 PM
god i just love you so much, this exactly same problem has annoyed me so much in the latest week...

looking at my xmldata from cfc arriving the alertbox was just heaven

lots of <3 ;-)
# Posted By Ola Muldal | 2/11/07 1:24 AM
The following is a completely AS3 scripted remoting call to the Flex2 gateway. To make life easier, simply make a copy of the services-config.xml file into the same folder as your project and than update it accordingly.

<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.remoting.RemoteObject;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;

private var profServicesRO:RemoteObject = new RemoteObject();

      public function onInit():void
       {
          profServicesRO.source = "profservices.components.statistics";
         profServicesRO.destination = "ColdFusion";
         populateGraph1();
       }

public function populateGraph1():void
{
profServicesRO.sayHello.addEventListener("result", populateGraph1Handler);
profServicesRO.addEventListener("fault", faultHandler);
profServicesRO.sayHello();
}

public function populateGraph1Handler(event:ResultEvent):void {
         // Do something
         Alert.show("THE SERVICE RETURNED BACK SUCCESSFULLY!","Returned");
}

public function faultHandler (event:FaultEvent):void {
         // Deal with event.faultstring, etc.
         Alert.show(event.fault.faultString, 'Error');
}
]]>
   </mx:Script>
# Posted By Kevin | 4/10/07 9:31 PM
Here's the example services-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<services-config>

<services>
<service id="coldfusion-flashremoting-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">

<adapters>
<adapter-definition id="cf-object" class="coldfusion.flash.messaging.ColdFusionAdapter" default="true"/>
</adapters>

<destination id="ColdFusion">
<channels>
<channel ref="my-cfamf"/>
</channels>
<properties>
<source>*</source>
<!-- define the resolution rules and access level of the cfc being invoked -->
<access>
<!-- Use the ColdFusion mappings to find CFCs, by default only CFC files under your webroot can be found. -->
<use-mappings>false</use-mappings>
<!-- allow "public and remote" or just "remote" methods to be invoked -->
<method-access-level>remote</method-access-level>
</access>

<property-case>
<!-- cfc property names -->
<force-cfc-lowercase>false</force-cfc-lowercase>
<!-- Query column names -->
<force-query-lowercase>false</force-query-lowercase>
<!-- struct keys -->
<force-struct-lowercase>false</force-struct-lowercase>
</property-case>
</properties>
</destination>

</service>
</services>

<channels>
<channel-definition id="my-cfamf" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://YOUR-DOMAIN-OR-IP/flex2gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
<polling-enabled>false</polling-enabled>
<serialization>
<instantiate-types>false</instantiate-types>
</serialization>
</properties>
</channel-definition>
</channels>

<logging>
<target class="flex.messaging.log.ConsoleTarget" level="Error">
<properties>
<prefix>[Flex] </prefix>
<includeDate>false</includeDate>
<includeTime>false</includeTime>
<includeLevel>false</includeLevel>
<includeCategory>false</includeCategory>
</properties>
<filters>
<pattern>Endpoint.*</pattern>
<pattern>Service.*</pattern>
<pattern>Configuration</pattern>
<pattern>Message.*</pattern>
</filters>
</target>
</logging>
# Posted By Kevin | 4/10/07 9:34 PM
Kevin,
so I need to use the config XML file? Is it not possible to specify the endpopint in AS code - this seems to be the only piece to the puzzle that's missing and not present in the AS version when compared to the MXML version of RemoteObject.
# Posted By Stefan | 4/12/07 5:11 PM
Dom, oh my gosh, thank you! I'm with Ola, I've never happy to see my "hello" from my test program. I've been looking everywhere about how to get my flash and coldfusion to talk to each other. So while the URL in the actionscript points to "http://localhost/flashservices/gateway/", the actual .cfc on the server is located at ".../cfusionmx/wwwroot/"
# Posted By Neb | 6/18/07 8:28 PM
sorry for my typo, that was supposed to say "I was very happy..."

If there a way to map the files so they don't have to be in "cfusionmx7/wwwroot/" without affecting anything else that might use coldfusion on that server?
# Posted By Neb | 6/18/07 8:55 PM
@Kevin

Did Stefan's last question ever get answered? How do you specify the endpoint in PureAS3? - I've been looking at ChannelSet, perhaps this is how it's done. Anyone?
# Posted By Devo | 6/22/09 8:06 PM
Hi Stefan,

I've just installed mamp and cf9 and for some reason my flex classes aren't mapping to the cfc's on the server. Have you had any issues with this?

They work on my remote server so I know the code is correct so it must be something to do with the way my vitual host is set up in mamp. here is my virtual host entry

DocumentRoot "/Users/cyberdaz/Sites/amwaymediaserver"
Alias /CFIDE "/Users/cyberdaz/Sites/CFIDE"
ServerName amwaymedia.local
</VirtualHost>
# Posted By Darren Bennett | 1/26/10 10:45 AM
Hi Daren,
sorry but I'm not sure what could cause this. Most likely a path issue of some kind?
# Posted By Stefan Richter | 1/26/10 12:15 PM
found it, it was case, my folder was title case whereas my apache path was lowercase.
# Posted By Darren Bennett | 1/26/10 12:26 PM