在试用了XML、JSON、AMF3后,最终不得不折服于AMF的高效率,AMF是个好东西,优点就不啰嗦了。在Google App Engine中使用AMF通信其实也很简单,只要加入PyAMF库即可。
1、Python端:
Echo的示例可以参考pyamf的官方文档。下面的例子展示了如何运用PyAMF访问数据库并序列号后返回给Flash端:
import datetime
import wsgiref.handlers
from pyamf.remoting.gateway.wsgi import WSGIGateway
from google.appengine.ext import db
def GetOwnerFlowers(platform, oid, max):
flowers = FlowerModel.all().filter('pid =', platform).filter('oid =', oid).order('-date').fetch(max)
return formatList(flowers)
def GetViewerFlowers(platform, oid, vid, max):
flowers = FlowerModel.all().filter('pid =', platform).filter('vid =', vid).filter('oid =', oid).order('-date').fetch(max)
return formatList(flowers)
def SaveFlower(data):
flower = FlowerModel()
flower.oid = data['oid']
flower.oname = data['oname']
flower.date = datetime.datetime.utcnow()
flower.put()
return True
def formatList(flowers, userCount, sysCount):
list = []
for flower in flowers:
result = {'oid':'', 'oname':'', 'date':''}
result['oid'] = flower.oid
result['oname'] = flower.oname
result['date'] = flower.date
list.append(result)
return list
services = {
'Garden.GetOwnerFlowers': GetOwnerFlowers,
'Garden.GetViewerFlowers': GetViewerFlowers,
'Garden.SaveFlower': SaveFlower
}
class FlowerModel(db.Model):
oid = db.StringProperty() #owner id
oname = db.StringProperty() #owner name
date = db.DateTimeProperty() #created date
def main():
application = WSGIGateway(services)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
2、Flash端不用做任何序列号的操作:
package com.moorwind.fans.utils
{
import com.moorwind.fans.core.Constant;
import com.moorwind.fans.core.Context;
import com.moorwind.fans.events.ServiceEvent;
import com.moorwind.fans.vo.FlowerVO;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.NetConnection;
import flash.net.Responder;
public class ServiceUtils extends EventDispatcher
{
private var conn:NetConnection = new NetConnection();
public function ServiceUtils()
{
conn.connect(Constant.END_POINT);
conn.addEventListener(IOErrorEvent.IO_ERROR, onConnectError);
conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onConnectError);
}
public function getOwner(oid:String, pid:int):void
{
var responder:Responder = new Responder(onGetOwner, onDataError);
conn.call(Constant.GET_OWNERS, responder, pid, oid, Constant.LIMIT);
}
public function getViewer(oid:String, vid:String, pid:int):void
{
var responder:Responder = new Responder(onGetViewer, onDataError);
conn.call(Constant.GET_VIEWERS, responder, pid, oid, vid, Constant.LIMIT);
}
public function saveFlower(flower:FlowerVO):void
{
var responder:Responder = new Responder(onSaveData, onDataError);
conn.call(Constant.SAVE_FLOWERS, responder, flower);
}
private function onGetOwner(result:Object):void
{
Context.instance.ownerTotal = result.userCount;
Context.instance.sysTotal = result.sysCount;
var arr:Array = [];
for each(var obj:Object in result.flowers)
{
var fl:FlowerVO = new FlowerVO();
fl.oid = obj["oid"];
fl.oname = obj["oname"];
arr.push(fl);
}
var evt:ServiceEvent = new ServiceEvent(ServiceEvent.FLOWER_OWNER);
evt.flowers = arr;
dispatchEvent(evt);
}
private function onGetViewer(result:Array):void
{
var arr:Array = [];
for each(var obj:Object in result)
{
var fl:FlowerVO = new FlowerVO();
fl.oid = obj["oid"];
fl.oname = obj["oname"];
arr.push(fl);
}
var evt:ServiceEvent = new ServiceEvent(ServiceEvent.FLOWER_VIEWER);
evt.flowers = arr;
dispatchEvent(evt);
}
private function onSaveData(result:Boolean):void
{
if(result)
{
dispatchEvent(new ServiceEvent(ServiceEvent.FLOWER_SAVED));
}
}
private function onDataError(result:Object):void
{
trace(result);
}
public function onConnectError(e:Event):void
{
trace(e);
}
}
}
唯一不好的是。。。使用PYAMF占用CPU太高,哎