Archive for the ‘AMF’ Category
pyamf is pretty sweet for Flash remoting with Pythonic server side, but now we have two nicely done and integrated remoting kits for python on the server side.
amfast is a new remoting library that looks to be as sweet as pyamf (where sweet == fast and useful). I am checking out amfast now but the speed boost alone might be worth it. For instance, working with real-time games, when you need static content you need to grab that quickly sometimes via a content service. The faster that link the better. It also has Twisted integration which is great for networking and SQLAlchemy integration which is in my opinion the best ORM for python (pyamf has twisted, django, pylons, sqlalchemy as well)
amfast is well documented and has some great examples. If you have the Python addiction, check it.
Description
- AmFast is a Flash remoting framework for Python.
- AmFast can use AMF to communicate between Python and Flash, Flex, and any other system that supports AMF.
- AMF is a binary object serialization protocol used by Actionscript based applications.
Server Features
- Support for NetConnection and RemoteObject RPC.
- Support for Producer/Consumer ‘push’ messaging with HTTP polling, HTTP long-polling, and real-time HTTP streaming channels.
- Support for authentication with NetConnection and RemoteObject.
- Flexible Target mapping system to map message destinations to invokable Target objects.
- Support for ChannelSets with multiple Channels to expose resources in different ways.
- Built in Channels for CherryPy, Twisted Web, and plain WSGI.
- Support for configurable Endpoints. Use AmFast’s built-in AMF encoder/decoder C-extension, or use an external AMF encoder/decoder, such as PyAmf for a pure-Python implementation.
AMF Encoder/Decoder Features
- AMF0/AMF3 encoder/decoder written in C as a Python extension for speed.
- More than 10x faster than the PyAmf encoder/decoder (even when using PyAmf’s optional C-extension).
- Map custom classes with ClassDef objects for complete control over serialization/de-serialization.
- Full support for IExternalizable objects.
- Data persistence with SqlAlchemy including remotely-loadable lazy-loaded attributes.
- Actionscript code generation from ClassDef objects.
A great Action Message Format (AMF) remoting kit for server side for the pythonistas is pyAMF, they recently released PyAMF 0.3 and have a sample running up on Google App Engine. There is also a tutorial for getting PyAMF running on Google App Engine. Aral Balkan got this running as well.
Features of pyAMF currently:
AMF0 encoder/decoder for legacy Flash Players (version 6-8).
- AMF3 encoder/decoder for the new AMF format in Flash Player 9.
- Support for IExternalizable, ArrayCollection, ObjectProxy, ByteArray (with zlib support), RecordSet and RemoteObject
- Remoting gateways for Twisted, Django, TurboGears2, Web2Py, Pylons and any compatible WSGI framework.
- Authentication/setCredentials support
- Remoting client using httplib with authentication support
- Service Browser (DescribeService header) requests supported
- Local Shared Object (LSO) support
- Adapter Framework to integrate nicely with third-party Python projects
More on the PyAMF library:
- Download — Download PyAMF
- Examples — Tutorials and examples
- Features — PyAMF features
- Documentation – General documentation
- Mailing List — Join the mailinglist for user and developer discussions
- Blog — Announcements and news
- IRC Channel — Chat and discuss PyAMF or get support
- Success Stories — See how PyAMF is being used
- Team — The people working on this project
- License — The project is licensed under the open source MIT license
Using SharedObjects in Flash is very simple. Flash has SharedObjects that have been in the player since Flash6 when the introduction of Flash Communication Server which is now Flash Media Server which is releasing version 3 soon (also remote SharedObjects in Red5 is an open source RTMP media server that is based on Flash Media Server). So we can thank this release for SharedObjects, Camera objects, Audio, lots of the NetConnections, protocol enhancements and many other things. However to keep the tips simple we will just touch on the local usage and post a series of posts on these objects.
SharedObjects locally and remote have changed the way offline is thought about and are the backbone of many offline systems and prototypes. They have been influential in moving storage locally to remote in a lightweight AMF0 or AMF3 format.
SharedObject is in the flash.net namespace in AS3.
Here we show how to use the local version of a SharedObject to store data in the most simple form.
import flash.net.SharedObject;
var so:SharedObject = SharedObject.getLocal("userData");
so.data.username= "user1377";
so.data.pwdhash= "[hash] or pwd";
so.flush(); // writes changes to disk
You can see this is extremely simple to store data.Here we show how to use the local version of a SharedObject to retrieve data in the most simple form.
import flash.net.SharedObject;
var so:SharedObject = SharedObject.getLocal("userData");
var username:String = so.data.username;
var pwdhash:String = so.data.pwdhash;
That is it! In the most basic form SharedObjects are more simple than cookies and also are quite nice living outside the bounds of the cookies folder. If a user deletes all cookies it will not delete the SharedObjects. To delete SharedObjects you need to roght click on the Flash player, go to Settings and delete the objects there.You can store any type of data Flash supports from objects to numbers to strings in the SharedObject data.
import flash.net.SharedObject;
var so:SharedObject = SharedObject.getLocal("userData");
so.data.username= "user1377";
so.data.uid= new Number(1337);
var obj:Object = new Object();
obj.prop = "value";
so.data.userobj= obj;
so.flush(); // writes changes to disk
For large applications SharedObjects local are great because users can have their SharedObject space set to a high amount of space or unlmited for large offline type apps or more complex apps stored in a state object. It gets interesting when you pass this to the server in AMF or extremely compact AMF3 format to a remote stored object, via remoting, Shared Object events or any way you want to.We will be posting more on remote shared objects and some of the other tools such as Camera and Streams for AS3 over the coming weeks and deeper into the Sync Events for remote and local SOs.Sephiroth has a great Python tool to peer into the SOs on disk.
The first version of SharedObject Reader was written in python 2.2.
This new version is written in C# (C Sharp) as it’s now part of FlashDevelop editor.
Red5 also does this as well as many AMF kits.
Sync Events for SharedObject (as they change they launch a sync event)
Event object type: flash.events.SyncEvent
SyncEvent.type property = flash.events.SyncEvent.SYNC
Read more at adobe docs:
Sample from AS3 docs showing usage
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.net.SharedObject;
import flash.net.SharedObjectFlushStatus;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
public class SharedObjectExample extends Sprite {
private var mySo:SharedObject;
public function SharedObjectExample() {
buildUI();
saveBtn.addEventListener(MouseEvent.CLICK, saveValue);
clearBtn.addEventListener(MouseEvent.CLICK, clearValue);
mySo = SharedObject.getLocal("application-name");
output.appendText("SharedObject loaded...\n");
output.appendText("loaded value: " + mySo.data.savedValue + "\n\n");
}
private function saveValue(event:MouseEvent):void {
output.appendText("saving value...\n");
mySo.data.savedValue = input.text;
var flushStatus:String = null;
try {
flushStatus = mySo.flush(10000);
} catch (error:Error) {
output.appendText("Error...Could not write SharedObject to disk\n");
}
if (flushStatus != null) {
switch (flushStatus) {
case SharedObjectFlushStatus.PENDING:
output.appendText("Requesting permission to save object...\n");
mySo.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
break;
case SharedObjectFlushStatus.FLUSHED:
output.appendText("Value flushed to disk.\n");
break;
}
}
output.appendText("\n");
}
private function clearValue(event:MouseEvent):void {
output.appendText("Cleared saved value...Reload SWF and the value should be \"undefined\".\n\n");
delete mySo.data.savedValue;
}
private function onFlushStatus(event:NetStatusEvent):void {
output.appendText("User closed permission dialog...\n");
switch (event.info.code) {
case "SharedObject.Flush.Success":
output.appendText("User granted permission -- value saved.\n");
break;
case "SharedObject.Flush.Failed":
output.appendText("User denied permission -- value not saved.\n");
break;
}
output.appendText("\n");
mySo.removeEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
}
// UI elements
private var inputLbl:TextField;
private var input:TextField;
private var output:TextField;
private var saveBtn:Sprite;
private var clearBtn:Sprite;
private function buildUI():void {
// input label
inputLbl = new TextField();
addChild(inputLbl);
inputLbl.x = 10;
inputLbl.y = 10;
inputLbl.text = "Value to save:";
// input TextField
input = new TextField();
addChild(input);
input.x = 80;
input.y = 10;
input.width = 100;
input.height = 20;
input.border = true;
input.background = true;
input.type = TextFieldType.INPUT;
// output TextField
output = new TextField();
addChild(output);
output.x = 10;
output.y = 35;
output.width = 250;
output.height = 250;
output.multiline = true;
output.wordWrap = true;
output.border = true;
output.background = true;
// Save button
saveBtn = new Sprite();
addChild(saveBtn);
saveBtn.x = 190;
saveBtn.y = 10;
saveBtn.useHandCursor = true;
saveBtn.graphics.lineStyle(1);
saveBtn.graphics.beginFill(0xcccccc);
saveBtn.graphics.drawRoundRect(0, 0, 30, 20, 5, 5);
var saveLbl:TextField = new TextField();
saveBtn.addChild(saveLbl);
saveLbl.text = "Save";
saveLbl.selectable = false;
// Clear button
clearBtn = new Sprite();
addChild(clearBtn);
clearBtn.x = 230;
clearBtn.y = 10;
clearBtn.useHandCursor = true;
clearBtn.graphics.lineStyle(1);
clearBtn.graphics.beginFill(0xcccccc);
clearBtn.graphics.drawRoundRect(0, 0, 30, 20, 5, 5);
var clearLbl:TextField = new TextField();
clearBtn.addChild(clearLbl);
clearLbl.text = "Clear";
clearLbl.selectable = false;
}
}
}