Back to home

Communicating between Flash and openFrameworks with AMF

At Apollo Media we work (besides building websites) on interactive intallations for museums.  These projects often involve multiple computers, multiple operating systems and are always networked. For each project we decide what programming environment and language suits the needs of the specific project.  Mostly we have a mix between some c++ coded applications and flash. When we create C++ applications openFrameworks is a nice solution because it has lots and lots of very usefull addons, has a extremely active community with nice, knowledge sharing people.  

Last year we used several different  ways to communicate between the computers/applications we created.  We tried OSC (which is awesome btw), stdin techniques, custom sockets, xml sockets etc..  All these solutions are well suited for networked communication, but they all need extra code on both Flash and C++/openFrameworks sides.  

For this project I wanted a solution for which I did not need to use other libraries;  The right solution for this is using the serialization protocol which is standard in Flash, called AMF. This is a binary protocol with a tiny overhead for encoding different data types; it has some smart ways of not sending the same object, array or byte array multiple times over the socket.  Instead it uses references to already transfered objects, array and byte arrays. 

To make this possible I added ofxAMFServer to the ofxFlashCommunication addon which creates a fast, tiny and simple AMF remoting server. Again, as the same with ofxFlashCommunication you need to add three lines of code to setup this scalable, multi threaded server. When you connect to this ofxAMFServer from Flash, you'll receive an ofxAMFEvent in your application.  This event object has a member function called getParams() which contains the parameters sent to it from Flash.  

void testApp::onAMFEvent(ofxAMFEvent& ev) {
	cout << "Request uri:" << ev.getTargetURI() << endl;
	cout << "Params (JSON): " << ev.getParams().toJSON() << endl;
	cout << "Params (XML):" << endl << ev.getParams().toXML() << endl;
	last_amf_params = ev.getParams().toXML();
	cout << "Data from flash:" << (string)ev.getParams()["data"] << endl;
 
	Dictionary result;
	result["name"] = "Some result";
	ev.setReturnValues(result);
}

These parameters are stored in a new type I created in my ofxMissing addon. It's called "Dictionary" and its main purpose is to create a generic "multi purpose, multi value" variable. This Dictonary type can store strings, integers, arrays etc.. It can transform the data to JSON and XML. 

To return data back to your Flash application you need to call setReturnValues(Dictionary) on the ofxAMFEvent object. (note: ofxAMFServer is really young and there will probably change some things in the future as this way of using events in multi threaded applications can lead to problems). 

Have a look at the example code which starts a basic AMF server. Then use the flash demo/test application I added to the repository to send some data to the demo app.

NOTE: You need both ofxFlashCommunication and ofxMissing in your project.