Improving on ColdFusion Remoting with Conduit

Since I've been working with Conduit,
there have been several 'enhancements' to the Flex Remoting that I've
implemented, above and beyond what ColdFusion provides out of the box.

These are mostly little things, but since Conduit is Open Source, we
are able to incorporate them into how Conduit works, and give us some
new tools to use when we set up Remoting.

One of the first enhancements I made, was around the fact that every time Flex invokes a CFC through Remoting,
it gets created on every request.  Quite often, this is simply not
necessary, as the CFC in question has no state, or maybe you want the CFC to maintain state, but you have to jump through some hoops to get that to happen.

In Conduit, you can now set a:


<cfcomponent remoteScope="application" >...</cfcomponent>


…and the CFC will be stored inside the specified shared scope.

For example, here is a CFC that gets stored in the session scope
when invoked, and keeps a simple incrementing number each time its
remote method gets called:

<cfcomponent hint="proxy stored in a share scope" output="false" remoteScope="session">

<cfscript>
    instance.value = 1;
</cfscript>

<cffunction name="getIncrementingValue" hint="returns a value, and increments it by 1" access="remote" returntype="numeric" output="false">
    <cfreturn instance.value++ />
</cffunction>

</cfcomponent>

So you can see here how we are able to maintain state between calls, within a single CFC.

The other enhancements I made, revolve around passing null values back and forth from AS3 Objects, and ColdFusion.

As we all know, there is no null as such in ColdFusion, which can make dealing with null values from Flex slightly problematic.

I've added two new enhancements to <cfproperty> for Value Objects to help with this issue – nullvalue and nullmethod.

nullvalue provides a value for a given property to be used when
a null value is found in a Flex AS3 object coming down to ColdFusion. 
This is particularly applicable when using getter/setters for your
properties on your ColdFusion Value Objects.

For example:

<cfcomponent output="false" alias="tests.cfml.cfc.model.Basic">

<cfproperty name="date" type="date" nullvalue="1-1-1900">

<cffunction name="getDate" access="public" returntype="date" output="false">
    <cfreturn instance.date />
</cffunction>

<cffunction name="setDate" access="public" returntype="void" output="false">
    <cfargument name="date" type="date" required="true">
    <cfset instance.date = arguments.date />
</cffunction>

</cfcomponent>


…will set 'Date' to the 1-1-1900 if the AS3 Object's 'date' property
is null.  Also, if sending data back up to Flex from CF, the 'date'
property is set to null on the Flex side, if the date value is
1-1-1900.  This gives you a type safe way of dealing with null values
coming down from Flex.

The nullMethod option for dealing with null values becomes more useful when dealing with object composition in Value Objects.

The nullmethod attribute specifies a method on the CFC to be fired, when encountering a null value for the specified method, e.g.

<cfcomponent output="false" alias="tests.cfml.cfc.model.Basic">

<cfproperty name="simple" type="tests.cfml.cfc.model.Simple" nullmethod="removeSimple">

<cffunction name="setSimple" access="public" returntype="void" output="false">
    <cfargument name="Simple" type="Simple" required="true">
    <cfset instance.Simple = arguments.Simple />
</cffunction>

<cffunction name="removeSimple" hint="remove simple" access="public" returntype="void" output="false">
    <cfset StructDelete(instance, "Simple") />
</cffunction>

</cfcomponent>

So in this case, whenever the property 'Simple' comes back from Flex as null, the method 'removeSimple' is called instead of attempting to set the property.

Now you can start to see what we can do with Conduit, since we can control all aspects of the Remoting process.  So the question is – if you could change any aspect of ColdFusion <=> Flex Remoting, what would it be?  Let me know, and we can see if we can incorporate it into Conduit!

If you want to read more, check out Differences between Conduit and ColdFusion remoting, in the Conduit documentation.

Leave a Comment

Comments

  • Nathan Mische | January 15, 2009

    Mark, this is some very cool stuff. Do you have any plans to expand Conduit into Flex Messaging as well?

    As for Remoting, One thing I would like to see is the ability to have Flex Remoting calls include the ColdFusion debugging template. Currently, if you have debugging enabled on the ColdFusion server, the debugging service runs for the Remoting request, but the debugging template is not called to output the debugging info. It makes sense for the default debugging templates, but it also means that you have to jump through some hoops if you want to use alternative debugging tools like ColdFire. (See this post for more info: http://www.mischefamily.com/nathan/index.cfm/2008/12/23/Debugging-Flex-with-ColdFire).

  • Mark | January 15, 2009

    @Nathan,

    Re: ‘Do you have any plans to expand Conduit into Flex Messaging as well?’, currently I don’t, simply because I don’t have the need for it, but it wouldn’t be hard to do, as its simply a different sort of BlazeDS Adapter required (I believe, I’d need to double check it).

    Re: ‘I would like to see is the ability to have Flex Remoting calls include the ColdFusion debugging template’ – that does sound very cool. How do you see this working? Does it show up in the debugging console of FlexBuilder?

    I liked what you did with ColdFire and Flex, that is very cool, you could probably do the same with Conduit, you would just have to cfinclude the coldfire.cfm file into your Application.cfc, onRequestEnd() function.

  • Nathan Mische | January 15, 2009

    Regarding Flex Messaging, the reason I ask is that I’m getting ready to start a project that is going to use a combination of Remoting and Messaging and it may be useful to target the same CFC and maintain state in a shared scope. I may have to take a closer look at the current Adapter and see if that is possible.

    Regarding debugging, I was originally thinking that a custom invoker could check to see if debugging is enabled and if so include the debugging template indicated in the ColdFusion administrator. The more I think about it though, assuming you could even find out what template to call and call it, I don’t think that would work. For example, if you were using classic.cfm its output would likely break Remoting. (Which is why, I’m sure, Adobe doesn’t run the debugging template for these requests.)

    What may be cool is to have a custom invoker that can do everything ColdFire does if the debugging service is running. (Basically all ColdFire does is serialize the debugging info as JSON and stick it in HTTP headers.) It may also be cool to have a custom serialiser that could take the same debugging data and put it in AMF headers. I’m not sure a Conduit searlizer can do that, but if it can you could then see the data as part of the AMF response in FlexBuilder. (ColdFusion supposedly does this but I’ve never been able to get it to work: http://blog.mikenimer.com/index.cfm/2008/10/13/RIA-Debugging-and-ColdFusion-forgotten-feature)

    Anyway just some ideas… I hope to get some time to actually play with Conduit soon.

  • Mark | January 15, 2009

    @Nathan, those are all some great ideas.

    Wanna help contribute them? 😀

  • Nathan Mische | January 16, 2009

    I plan to take a look at building the invoker as soon as I get some free time. I’d also be interested in working on the serialiser, but that may take a little more research.