<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>AaronHardy.com &#187; amf</title>
	<atom:link href="http://aaronhardy.com/tag/amf/feed/" rel="self" type="application/rss+xml" />
	<link>http://aaronhardy.com</link>
	<description>For all your Aaron Hardy needs.</description>
	<lastBuildDate>Fri, 20 Apr 2012 14:53:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>RedLiteGreenLite</title>
		<link>http://aaronhardy.com/flex/redlitegreenlite/</link>
		<comments>http://aaronhardy.com/flex/redlitegreenlite/#comments</comments>
		<pubDate>Sun, 30 May 2010 21:44:42 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[General Programming]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[amf]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[Google Apps Engine]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[messaging]]></category>
		<category><![CDATA[polling]]></category>
		<category><![CDATA[remoting]]></category>
		<category><![CDATA[RobotLegs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=658</guid>
		<description><![CDATA[Please upgrade your Flash Player This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed. What is it? RedLiteGreenLite is a small, simple app that allows a group of people to communicate the status of something. The status can be either red or green and [...]]]></description>
			<content:encoded><![CDATA[<p><div id="flashcontent1382" style="width:215px; height:180px;"><strong>Please upgrade your Flash Player</strong> This is the content that would be shown if the user does not have Flash Player 9.0.115 or higher installed.</div><script type="text/javascript">
<!-- // <![CDATA[
var so = new SWFObject("http://aaronhardy.com/wp-content/plugins/air-badge/AIRInstallBadge.swf", "Badge", "215", "180", "9.0.115", "#343434");
so.useExpressInstall("http://aaronhardy.com/wp-content/plugins/air-badge/expressinstall.swf");
so.addVariable("airversion", "1.0");
so.addVariable("appname", "RedLiteGreenLite");
so.addVariable("appurl", "http://aaronhardy.com/rlgl/RedLiteGreenLite.air");
so.addVariable("appid", "RedLiteGreenLite");
so.addVariable("pubid", "");
so.addVariable("appversion", ".5");
so.addVariable("imageurl", "/rlgl/rlglinstallbadge.jpg");
so.addVariable("appinstallarg", "installed from web");
so.addVariable("applauncharg", "launched from web");
so.addVariable("helpurl", "help.html");
so.addVariable("hidehelp", "true");
so.addVariable("skiptransition", "false");
so.addVariable("titlecolor", "#00AAFF");
so.addVariable("buttonlabelcolor", "#00AAFF");
so.addVariable("appnamecolor", "#00AAFF");
so.addVariable("str_err_airswf", "<u>Running locally?</u><br/><br/>The AIR proxy swf won't load properly when this is run from the local file system.");
so.write("flashcontent1382");
// ]]&gt; -->
</script>
</p>
<h3>What is it?</h3>
<p>RedLiteGreenLite is a small, simple app that allows a group of people to communicate the status of something.  The status can be either red or green and the subject can be whatever.  That may sound a bit general, but that&#8217;s the point.  It can be used for whatever purpose your crazy mind can come up with.  I&#8217;ll get you started:</p>
<ol>
<li>At work, we have a single shower and a lot of shweaty guys after soccer.  So we know when the shower&#8217;s available, someone can turn the status red when he enters the shower and turn it green when he exits.  This way nobody has to keep stopping by the shower to see if it&#8217;s available.  When it&#8217;s green, it&#8217;s available.   When it&#8217;s red, it&#8217;s not.</li>
<li>At a call center, representatives are split into groups. When one group is on break, no other group is allowed to go on break.  Again, when the status is red, a group is on break and other groups must continue attending the phones.  When the lite is green, the next group is free to take a break.</li>
</ol>
<p>The process is pretty simple: join a group.  Other people join the same group.  When others in the group change the status, you&#8217;ll be notified.  When you change the status, others in the group will be notified.  The status of the group will be persisted across sessions.  In other words, if everyone logs out and then logs back in a week later, the status will remain as it was the last time it was set.<span id="more-658"></span></p>
<p>There&#8217;s no need to explicitly create a group.  When you attempt to join a group, the group will automatically be created if it does not already exist.</p>
<p>The app is free.  As in free free.</p>
<h3>What technologies are used?</h3>
<p>RedLiteGreenLite has a client portion and a server portion.</p>
<p>The client is the app users download and install on their computers.  It&#8217;s built in <a href="http://www.adobe.com/products/flex/" target="_blank">Flex</a> and published for <a href="http://www.adobe.com/products/air/" target="_blank">AIR</a>.  It uses the <a href="http://www.robotlegs.org/" target="_blank">RobotLegs</a> MVCS framework and makes use of <a href="http://en.wikipedia.org/wiki/Action_Message_Format" target="_blank">AMF</a> remoting and messaging.</p>
<p>The server portion is built in <a href="http://www.java.com/en/" target="_blank">Java</a> using <a href="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/" target="_blank">BlazeDS</a> and is hosted on <a href="http://code.google.com/appengine/" target="_blank">Google Apps Engine</a>.</p>
<h3>Ooh, that&#8217;s simply juicy.  Tell me more.</h3>
<p>Don&#8217;t mind if I do.  First of all, BlazeDS is an open source implementation of AMF-based remoting and messaging.  Natively it&#8217;s not compatible with Google Apps Engine, but I wanted to use GAE because it&#8217;s extremely scalable, it&#8217;s free (let&#8217;s be honest&#8211;I&#8217;m cheap like that&#8211;this is the main reason), and I wanted the challenge.</p>
<p>To get BlazeDS working on GAE, I recommend following <a href="http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html" target="_blank">Martin Zoldano&#8217;s blog post</a>.  Not only does he outline the steps you&#8217;ll need to take but he provides a critical patch to flex-messaging-core.jar as well.  While you can find this patch re-distributed elsewhere, I recommend posting a comment requesting that he email you the patched jar.  That&#8217;s how he seems to want to distribute his patch and I respect that.  He&#8217;s really helpful and quick to respond so it shouldn&#8217;t be much trouble.</p>
<p>Once BlazeDS was set up and configured, I started to plan the architecture.  First of all, I needed one client in the group to be able to send a message to the rest of the clients in the group.  This could be achieved through the messaging service BlazeDS provides.  However, messaging doesn&#8217;t store state; it just redistributes messages to clients.  I needed the group&#8217;s status to be persisted to storage so (1) when a new client joins a group it can retrieve the group&#8217;s current status and (2) the group&#8217;s status can be retained even when no clients are connected.</p>
<p>By default, BlazeDS&#8217;s messaging configuration uses ActionScriptAdapter to receive and distribute messages between clients.  It doesn&#8217;t persist messages.  To do so, I extend ActionScriptAdapter and persist the status to Google Storage before sending the message out to the other clients.  When clients connect to BlazeDS, they use remoting (not messaging) to retrieve the most recently persisted status for the group.  After the initial status is retrieved, the client talks to other clients using the messaging service.  You can see how this is set up in messaging-config.xml and PersistentASAdapter.java in the <a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">server code</a>.</p>
<p>While GAE has been really nice to get the app up and running, it does have its downsides.  To send messages between clients, BlazeDS can use a few different techniques:</p>
<ul>
<li>Simple polling. The client, at a standard interval, simply asks the server if there is any new information.  The server responds to the request immediately regardless of whether there is new information.</li>
<li>Long polling. The client sends a request to the server.  The server holds onto the request until it has something useful to tell the client at which time it sends back the response.</li>
<li>Streaming.  The client opens an HTTP connection and the connection remains open.  The server shoots messages down the connection whenever it has something to say.  It&#8217;s an &#8220;infinate response&#8221;.</li>
</ul>
<p>While <a href="http://www.dcooper.org/blog/client/index.cfm?mode=entry&#038;entry=8E1439AD-4E22-1671-58710DD528E9C2E7" target="_blank">each approach has its pros and cons</a>, simple polling leaves a lot to be desired as it creates a lot of HTTP traffic.  Unfortunately, from my testing and research, GAE doesn&#8217;t seem to support either of the other two methods.  But hey, it&#8217;s free.  If any of you have a java environment and would like to host RedLiteGreenLite so we can step up our game, let me know.</p>
<p>Last but not least, RedLiteGreenLite is open source.  I&#8217;d love for you to <a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">fork the project</a> and do something cool with it.</p>
<p>Now go have fun!  Install the client using the badge at the top of the post or fork the project using the link below.</p>
<div class="goodies"><a href="http://github.com/Aaronius/RedLiteGreenLite" target="_blank">Fork Project</a><br class="break"></div>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/redlitegreenlite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Why, What, and Where of Custom AMF Class Adapters</title>
		<link>http://aaronhardy.com/flex/the-why-what-and-where-of-custom-amf-class-adapters/</link>
		<comments>http://aaronhardy.com/flex/the-why-what-and-where-of-custom-amf-class-adapters/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 04:04:07 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[General Programming]]></category>
		<category><![CDATA[amf]]></category>
		<category><![CDATA[class adapters]]></category>
		<category><![CDATA[coupling]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=77</guid>
		<description><![CDATA[If you&#8217;ve read my article on Action Message Format (AMF) you&#8217;ll already know that AMF is a super-duper way to transfer data between a Flex/Flash/AIR application and its server-side counterpart.  Essentially when the client application makes a call to a service, the server can return a Java (or PHP, Python, .NET) object and when it [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">If you&#8217;ve read <a href="/flex/simple-amfphp-example/" target="_blank">my article</a> on <a href="http://en.wikipedia.org/wiki/Action_Message_Format" target="_blank">Action Message Format</a> (AMF) you&#8217;ll already know that AMF is a super-duper way to transfer data between a Flex/Flash/AIR application and its server-side counterpart.  Essentially when the client application makes a call to a service, the server can return a Java (or PHP, Python, .NET) object and when it gets back to the Flex application, wallah, its converted into an identical object in ActionScript.  Similarly, if the client application sends an ActionScript object to the server during a service call, it arrives as an identical Java object.</p>
<p style="text-align: left;">While that&#8217;s impressive, when it comes to implementation in a medium-to-high complexity system there are questions that still need to be answered.   In this article, I&#8217;d like to address where to translate custom AMF classes.</p>
<p style="text-align: left;"><span id="more-77"></span></p>
<p style="text-align: left;"><strong>The Why</strong></p>
<p style="text-align: left;">When server-side code accesses data from a database, it generally converts the data in the recordset into data objects (sometimes called beans, business objects, or one of many other names.)  These are basic objects that often, though not always, represent the shema of the database.  In other words, if there&#8217;s a table named <em>customer</em> in the database, there will likely be a class named <em>customer </em>as well.  One customer object instance represents one customer record in the database.  With frameworks like Rails, Cake, and Django, this is almost always true.</p>
<p style="text-align: left;">If a Flex application is requesting all customers, the process of retrieving the data is fairly simple: Flex makes a call to the service, the service retrieves all customer records from the database, the service converts each customer record into an customer object, and finally the service returns the array of customer objects back to the Flex application.</p>
<p style="text-align: left;">In order for the previous example to function correctly, an ActionScript customer class must exist on the Flex client as well as an identical Java customer class on the server.  Considering the most common case, these two classes will have properties that match the fields in the customer table.  In other words, both of these classes as well as the customer table will have properties such as firstName, lastName, phoneNumber, address, zipcode, etc.  With that in mind, what happens when a developer begins to refactor the application and chooses to rename the <em>phoneNumber </em>database field to <em>homePhone</em>?  The phoneNumber property in both the ActionScript customer class and the Java customer class will need to be renamed to homePhone.  This means there is <a href="http://en.wikipedia.org/wiki/Coupling_(computer_science)" target="_blank">high coupling</a> among the database, the backend application, and the frontend application.  In other words, each part needs to know about the other two parts.  This breaks good programming principles because it results in more difficult maintenance.</p>
<p style="text-align: left;">This high coupling magnifies itself further if we wish to have the Flex application&#8217;s needs drive the design of the data objects.  Lets say we as Flex developers are creating a Flex application and know we want a salesperson&#8217;s first name, last name, sales code, and whether the salesperson is a system admin.  Now let&#8217;s say the database has already been designed and for whatever reason the salesperson&#8217;s firstName and lastName are in one table, the sales code is in a different table, and the system admin rights are in another.  Without some sort of conversion adapter, we will be shipping objects created from three different classes (Class A related to Table A, Class B related to Table B, and Class C related to Table C) from the server to the Flex frontend.  The following diagram illustrates the data flow.</p>
<p style="text-align: left;"><a href="http://aaronhardy.com/wp-content/uploads/2008/09/no-adapter.gif"><img class="aligncenter size-full wp-image-83" title="No Adapter" src="http://aaronhardy.com/wp-content/uploads/2008/09/no-adapter.gif" alt="" width="500" height="376" /></a></p>
<p style="text-align: left;">Why does this high coupling present a problem?  Here are a few issues to think about:</p>
<p style="text-align: left;">(1) If the backend developer chooses to refactor the database table by combining Table A and Table B, the Java classes AND the ActionScript classes must also be refactored.  If we&#8217;re talking about production code, that means refactoring ActionScript code and redeploying the SWF.  In the case of an AIR app, the AIR application on each client computer must be upgraded.</p>
<p style="text-align: left;">(2) The Flex frontend probably does not, and to promote low coupling, <em>should not</em>, care about how the database was designed.  This is more an issue of principle, but if the frontend developer is mentally detached from the database schema, the frontend application&#8217;s modeling, logic, and architecture will in general likely also be decoupled from the database schema.</p>
<p style="text-align: left;">(3) Having three different ActionScript classes to get our salesperson information doesn&#8217;t necessarily make sense.  Maybe there was a reason to have the information in three different database tables, but the reasoning may not apply when it comes to the Flex frontend.  Having three different classes means more overhead and maintenance.</p>
<p style="text-align: left;">(4) Even simple differences such as coding style must be maintained across the database, backend code, and frontend code.  If the database fields were creating using underscores such as first_name, last_name, home_phone, etc., this style must be also be used in the backend code and the frontend code.  Considering most Flex developers use camelCase name styling (firstName, lastName, homePhone,) this coupling presents an inconsistency in style.</p>
<p style="text-align: left;"><strong>The What</strong></p>
<p style="text-align: left;">So, how do we deal with these issues?  Generally the best solution is to create an adapter or layer that converts objects the backend uses to objects the frontend needs.  The backend and frontend agree on the classes that will be sent across the wire and those classes essentially become a contract&#8211;an agreement between the frontend and backend on what will be sent and received.  These classes should be designed without regard to database schema or the classes the backend uses within its own domain.  In our example, Flex needs objects of Class X which includes a salesperson&#8217;s first name, last name, sales code, and whether the salesperson is a system admin.  The backend is already using Class A, Class B, and Class C that contain these various properties.  The adapter would take objects of Class A, Class B, and Class C and combine the needed properties into an object of Class X.  Class X is essentially the contract&#8211;both the backend and frontend have agreed that Class X is what will be sent and received.</p>
<p style="text-align: left;">Not only does an adapter allow for the creation of objects that are slim-and-trim and customized for Flex&#8217;s needs, but of even greater importance is it provides a point of decoupling.  If the field in a database table gets renamed, the related property in the frontend class does not need to be renamed.  Instead, only the adapter needs modified so the <em>new backend property name</em> is mapped to the <em>old frontend property name</em>.  This adapter also provides for a place to convert programming style (<em>first_name</em> on the backend would be mapped to <em>firstName</em> on the frontend.)</p>
<p style="text-align: left;"><strong>The Where</strong></p>
<p style="text-align: left;">Now that you (hopefully) understand what adapters are and why they&#8217;re helpful, the remaining question is where the adapter should be implemented.  Two possible locations are the most logical: (1) on the backend immediately before sending objects to the frontend or (2) on the frontend immediately after receiving objects from the backend.  The data flow process for each of these adapter locations is illustrated in the following diagrams.</p>
<p style="text-align: left;"><a href="http://aaronhardy.com/wp-content/uploads/2008/09/backend-adapter.gif"><img class="aligncenter size-full wp-image-84" title="Backend Adapter" src="http://aaronhardy.com/wp-content/uploads/2008/09/backend-adapter.gif" alt="" width="500" height="376" /></a></p>
<p style="text-align: left;"><a href="http://aaronhardy.com/wp-content/uploads/2008/09/frontend-adapter.gif"><img class="aligncenter size-full wp-image-85" title="Frontend Adapter" src="http://aaronhardy.com/wp-content/uploads/2008/09/frontend-adapter.gif" alt="" width="500" height="376" /></a></p>
<p style="text-align: left;">Here are the benefits of each location as I see them:</p>
<p style="text-align: left;">On the backend immediately before sending objects to the frontend:</p>
<ul>
<li>Database schema changes do not have any affect on frontend code (except for changes fundamental to application logic.)  This means when the database schema changes, the Flex/Flash/AIR application does not need to be recompiled and redeployed.  If the adapter were on the frontend, the adapter would need to be updated, resulting in the need to be recompiled and redeployed.</li>
<li>In a team environment, a backend developer can modify the database schema and commit changes to the backend classes and accompanying adapter almost simultaneously. Frontend development remains virtually uninterrupted.  If the adapter was on the frontend, the backend developer would make the change to the database schema and commit the changes to the backend classes.  The backend developer would then need to notify the frontend developer of the change.  The frontend developer would then modify the adapter and commit its change.   Throughout the duration between the backend developer&#8217;s commit and the frontend developer&#8217;s commit, the Flex application would not function correctly. Because the frontend is generally more concerned with the presentation of data rather than heavy analysis, data mining, integration with ecommerce, and other data-centric tasks, frontend developers will likely require less refactoring of data models than backend developers.  By having the adapter on the backend, less communication between developers will be required when refactoring.</li>
<li>Keeping adapter code out of the frontend results in a smaller SWF/AIR file size.</li>
<li>Conversion tasks carried out by the adapter require processing.  By keeping processing on the server, processing time is more predictable and manageable than if the processing were performed on the client.</li>
</ul>
<p>On the frontend immediately after receiving objects from the backend:</p>
<ul>
<li>The backend does not need to know how frontend data is modeled.  In other words, if a frontend developer would like to rename a property in the data model&#8217;s class or combine two classes, the backend does not need to be notified.  If the adapter were instead on the backend, the application would be broken during the duration between when the frontend developer commits the data model&#8217;s class change and the backend developer commits the backend class and adapter change.  However, like I mentioned previously, it&#8217;s been my experience that the frontend requires less data model refactoring than the backend.</li>
</ul>
<p>As you may have concluded from the analysis, it&#8217;s fairly clear the best location for the adapter is on the backend just before sending objects to the frontend.  While having an adapter or at least some level of abstraction in the first place is certainly the most important concept, having an adapter in the right location can also help.</p>
<p style="text-align: left;">Do you disagree or have a perspective not addressed in my analysis?  Do you have questions regarding the why, what, and where of custom class adapters?  I invite you to join in on the conversation by responding below.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/the-why-what-and-where-of-custom-amf-class-adapters/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Simple AMFPHP Example</title>
		<link>http://aaronhardy.com/flex/simple-amfphp-example/</link>
		<comments>http://aaronhardy.com/flex/simple-amfphp-example/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 04:24:14 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[amf]]></category>
		<category><![CDATA[AMFPHP]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://intimateconversations.aaronhardy.com/php/simple-amfphp-example/</guid>
		<description><![CDATA[With the advent of Flex and RIA (Rich Internet Application) development came AMF (Action Message Format). Flex, in general, focuses only on front-end functionality, meaning it does not directly hit a database to store or retrieve persistent data. Instead, database calls are written in a more traditional back-end language like Java, PHP, Python, or .NET [...]]]></description>
			<content:encoded><![CDATA[<p>With the advent of Flex and RIA (Rich Internet Application) development came AMF (Action Message Format).  Flex, in general, focuses only on front-end functionality, meaning it does not directly hit a database to store or retrieve persistent data.  Instead, database calls are written in a more traditional back-end language like Java, PHP, Python, or .NET and such services are then exposed to be &#8220;consumed&#8221; (used) by the Flex front-end.</p>
<p>AMF is a protocol that allows ActionScript (the language of Flash/Flex) to call services exposed by the back-end.  Additionally, if you choose, AMF allows you to translate a programmer-defined object between ActionScript and your back-end language of choice.  In other words, if you have a customer class in ActionScript and you want to pass an instantiated customer object to the back-end, you simply call the exposed back-end service and pass the customer object as a parameter.  The AMF layer transparently translates the ActionScript customer object into, let&#8217;s say, a customer object in Java.  This functionality isn&#8217;t required.  Instead of using a class you have defined, you could instead just send an integer to the backend as a parameter and, after processing, send a string back to the front-end.<span id="more-33"></span></p>
<p>Before checking out my example, I recommend checking out the <a href="http://en.wikipedia.org/wiki/Action_Message_Format" target="_blank">Wikipedia Action Message Format article</a> to get a basic description of AMF and links to implementations for various back-end languages.  I also recommend reading <a href="http://nothinghappens.net/?p=198" target="_blank">AMFPHP class mapping explained</a> by Chuck Hoffman to get a good understanding of the object translation I just described.  Finally, head on over to <a href="http://amfphp.org/" target="_blank">amfphp.org</a> (the creators of AMFPHP) to get a glimpse of available documentation, files, etc.  I might add that if any of the folks over at amfphp.org don&#8217;t like me distributing AMFPHP code, let me know and I&#8217;ll modify the files I&#8217;ve posted for download.  The zip file below currently contains everything you&#8217;ll need to get a simple example up and running.  Now to the example&#8230;</p>
<p><a href='/wp-content/uploads/2008/02/simpleamfphp.zip' title='Simple AMFPHP Example'>Simple AMFPHP Example Zip File</a></p>
<p>For the example, I made a Kite Finder.  Basically, you enter in a kite pilot&#8217;s name and Flex populates a person object with the pilot name entered.  Flex then calls a PHP service function using AMFPHP which translates the ActionScript person object to a PHP person object on the backend.  In a real environment, you would then use information from the person object to hit a database to find the pilot&#8217;s kite.  In our example, we just build a kite object using dummy data.  Our PHP function then returns the kite object, which AMFPHP ships back to the Flex front-end, translating it to an ActionScript kite object.  In reality, the person and kite classes might be a little overboard for such a simple example.  I could&#8217;ve just passed two string parameters (the pilot&#8217;s first and last name) to the PHP function and an associative array (kite info) back to the front-end, but I wanted to demonstrate AMFPHP&#8217;s object translation.</p>
<p>Setting up the example is fairly easy:</p>
<ol>
<li>Upload the amfphp directory to the root directory of your website.</li>
<li>Open the SimpleAMFPHP project in FlexBuilder and modify the &#8220;gateway&#8221; variable in FindKiteCommand to point to your new gateway address.</li>
</ol>
<p>That&#8217;s all!  You should be able to deploy the project from within FlexBuilder and see it in action.  This should work even if you&#8217;re using <a href="http://www.hostingobserver.com" target="_blank">inexpensive web hosting</a>.  If you have questions on where code is, what&#8217;s happening, how to do something, or anything else, please&#8230;join the intimate conversation!</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/simple-amfphp-example/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

