Flash applications have always been, thanks to classes like XMLSocket, a good client for push http services. On the web you can find many chat applications, on the client, instead, it's quite common to connect the application to a local proxy server. This proxy servers usually create an http socket on localhost and send to the Flash clients via TCP any kind of data as string. On ActionScript3 the Socket class, and some others, can read directly byte arrays and it becomes really easy to send optimized data packages to the Flash client. Let see an example!
I was playing with a small application in C++ built with openframeworks, that sends to the Flash client as package a model that contains mouse coordinates and the distance to the screen. Think about a touch-less interface sensor layer, for instance. The C++ class would be:
// model.h
#ifndef _MODEL
#define _MODEL
class Model
{
public:
Model(void);
~Model(void);
int x;
int y;
float depth;
};
#endif
This class specifies its attributes, and most important, their order.
So if I send an instance via socket using OF (openframework) ofxTCPServer :
ofxTCPServer.sendRawBytesToAll((char*) modelInstance, sizeof(Model));
In Flash I can easily retrieve the values in this way:
var x : int = mySocket.readInt();
var y : int = mySocket.readInt();
var d : Number = mySocket.readFloat();
The package sent each time is 4+4+4 bytes and is sent pretty quickly :)
An abstract class that fills itself based on its attributes could also be made. Here a very quick draft:
// VariableType.as
package com.conchango
{
public class VariableType
{
public static const INT : VariableType = new VariableType("int",4,"readInt");
public static const NUMBER : VariableType = new VariableType("Number",4,"readFloat");
public var name : String;
public var size : int;
public var readMethod : String;
private static var map : Object;
public function VariableType (name : String, size : int, readMethod : String)
{
this.name = name;
this.size = size;
this.readMethod = readMethod;
register(this);
}
private static function register (type : VariableType) : void
{
if(map == null)
map = {};
map[type.name] = type;
}
public static function getTypeByName (name : String) : VariableType
{
return map[name] as VariableType;
}
}
}
// Streamable.as
package com.conchango
{
import flash.utils.getQualifiedClassName;
import flash.utils.IDataInput;
public class Streamable
{
public function Streamable (input : IDataInput)
{
var attribute : String;
var typeName : String;
var type : VariableType;
for each(attribute in attributesList)
{
typeName = getQualifiedClassName(this[attribute]);
type = VariableType.getTypeByName(typeName);
this[attribute] = input[type.readMethod]();
}
}
protected function get attributesList () : Array
{
return [];
}
public function get size () : int
{
var res : uint;
var attribute : String;
var typeName : String;
var type : VariableType;
for each(attribute in attributesList)
{
typeName = getQualifiedClassName(this[attribute]);
type = VariableType.getTypeByName(typeName);
res += type.size;
}
return res;
}
}
}
// Model.as
package com.conchango
{
import flash.utils.IDataInput;
public class Model extends Streamable
{
public var x : int;
public var y : int;
public var depth : Number;
public function Model(input : IDataInput){
super(input);
}
override protected function get attributesList():Array
{
return ["x","y","depth"];
}
}
}
Really cool thing would be to send serialized objects to Flash using AMF3 protocol, but unfortunately I couldn't find at the moment any porting of it for C++, I might try with Java soon though.
Other interesting aspect is that Flash Player 10 will support UDP, as OF does, but unfortunately its peculiarity of not check every packet won't be make it suitable for any application.