例子摘自官方文檔:
這是服務端代碼:Server.py
# Copyright (c) The PyAMF Project.
# See LICENSE.txt for details.
"""
Simple PyAMF server.
@see: U{Simple Example<http://pyamf.org/tutorials/actionscript/simple.html>} documentation.
@since: 0.5
"""
import logging
from wsgiref import simple_server
import pyamf
from pyamf import amf3
from pyamf.remoting.gateway.wsgi import WSGIGateway
#:路徑名,用於flex接收Object時的類型轉換 [RemoteClass] mapping
AMF_NAMESPACE = 'org.pyamf.examples.simple'
#: 提供服務的地址跟端口
host_info = ('localhost', 8000)
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s')
def create_user(username, password, email):
"""
創建一個用戶
"""
user = User(username, password, email)
return user
class User(object):
"""
Models information associated with a simple user object.
"""
# we need a default constructor (e.g. a paren-paren constructor)
def __init__(self, username=None, password=None, email=None):
"""
Create an instance of a user object.
"""
self.username = username
self.password = password
self.email = email
class UserService(object):
"""
提供服務
"""
def __init__(self, users):
"""
Create an instance of the user service.
"""
self.users = users
def get_user(self, username):
"""
Fetch a user object by C{username}.
"""
try:
return self.users[username]
except KeyError:
return "Username '%s' not found" % username
class EchoService(object):
"""
Provide a simple server for testing.
"""
def echo(self, data):
"""
Return data with chevrons surrounding it.
"""
return '<<%s>>' % data
def register_classes():
"""
Register domain objects with PyAMF.
"""
# set this so returned objects and arrays are bindable
amf3.use_proxies_default = True
# register domain objects that will be used with PyAMF
pyamf.register_class(User, '%s.User' % AMF_NAMESPACE)
def main():
"""
Create a WSGIGateway application and serve it.
"""
# register class on the AMF namespace so that it is passed marshaled
register_classes()
# use a dict in leiu of sqlite or an actual database to store users
# re passwords: plain-text in a production would be bad
users = {
'lenards': User('lenards', 'f00f00', '[email protected]'),
'lisa': User('lisa', 'h1k3r', '[email protected]'),
}
# our gateway will have two services
services = {
'echo': EchoService,
'user': UserService(users)
}
# setup our server
application = WSGIGateway(services, logger=logging)
httpd = simple_server.WSGIServer(host_info,
simple_server.WSGIRequestHandler)
httpd.set_app(application)
try:
# open for business
print "Running Simple PyAMF gateway on http://%s:%d" % (
host_info[0], host_info[1])
httpd.serve_forever()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-p", "--port", default=host_info[1],
dest="port", help="port number [default: %default]")
parser.add_option("--host", default=host_info[0],
dest="host", help="host address [default: %default]")
(options, args) = parser.parse_args()
host_info = (options.host, options.port)
# now we rock the code
main()
測試服務是否成功,Client.py
# Copyright (c) The PyAMF Project.
# See LICENSE.txt for details.
"""
Simple PyAMF client.
@see: U{Simple Example<http://pyamf.org/tutorials/actionscript/simple.html>} documentation.
@since: 0.5
"""
import logging
from server import AMF_NAMESPACE, host_info
import pyamf
from pyamf.remoting.client import RemotingService
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s')
class UserDataTransferObject(object):
"""
Models information associated with a simple user object.
"""
# a default paren-paren constructor is needed for classes
# that will be passed via AMF
def __init__(self, username=None, password=None, email=None):
"""
Create an instance of a user object.
"""
self.username = username
self.password = password
self.email = email
def main():
"""
Entry point for this client script.
"""
url = 'http://%s:%d' % (host_info[0], host_info[1])
client = RemotingService(url, logger=logging)
print "Client running - pointing to server at %s" % url
# at this point, calling the service gets us a dict of values
user_service = client.getService('user')
lenards = user_service.get_user('lenards')
# in case you don't believe me - this shows I'm not lying
logging.debug("isinstance(lenards, dict): %s" % isinstance(lenards, dict))
# the User class attributes are not present at this point
logging.debug("not hasattr(lenards, 'username'): %s" %
(not hasattr(lenards, 'username')))
logging.debug("not hasattr(lenards, 'email'): %s" %
(not hasattr(lenards, 'email')))
logging.debug("not hasattr(lenards, 'password'): %s" %
(not hasattr(lenards, 'password')))
# but the values are there
logging.debug("lenards['username'] == 'lenards': %s" %
(lenards['username'] == 'lenards'))
logging.debug("lenards['email'] == '[email protected]': %s" %
(lenards['email'] == '[email protected]'))
logging.debug("Output 'lenards': %s" % lenards)
# if we register the class and the namespace, we get an object ref
# (complete with attributes and such)
logging.debug("Register UserDataTransferObject class...")
pyamf.register_class(UserDataTransferObject, '%s.User' % AMF_NAMESPACE)
logging.debug("Get a user from the server...")
usr = user_service.get_user('lisa')
# ensure it's the class we expect
logging.debug("Ensure the class we got is our DTO, " +
"isinstance(usr, UserDataTransferObject): %s" %
isinstance(usr, UserDataTransferObject))
# verify it has expected attributes
logging.debug("Verify attributes present...")
logging.debug("usr.username: %s" % usr.username)
logging.debug("usr.email == '[email protected]': %s" %
(usr.email == '[email protected]'))
logging.debug("usr.password == 'h1k3r': %s" %
(usr.password == 'h1k3r'))
logging.debug("Output user returned: %s" % usr)
# request an unknown user
logging.debug("Try to get a user that does not exist...")
george = user_service.get_user('george')
logging.debug("Output returned: %s" % george)
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser()
parser.add_option("--host", default=host_info[0],
dest="host", help="host address [default: %default]")
parser.add_option("-p", "--port", default=host_info[1],
dest="port", help="port number [default: %default]")
(options, args) = parser.parse_args()
# host_info[0] = options.host
# host_info[1] = int(options.port)
# now we rock the code
main()
Flex程序
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="application1_creationCompleteHandler(event)">
<fx:Declarations>
<!-- 將非可視元素(例如服務、值對象)放在此處 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.messaging.ChannelSet;
import mx.messaging.channels.AMFChannel;
import mx.rpc.AbstractOperation;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
private static const URL : String = "http://localhost:8000";
private var _service : RemoteObject;
private function initializeService():RemoteObject
{
var channel:AMFChannel = new AMFChannel("pyamf-channel", URL);
var channels:ChannelSet = new ChannelSet();
channels.addChannel(channel);
var remoteObject:RemoteObject = new RemoteObject("user");
remoteObject.showBusyCursor = true;
remoteObject.channelSet = channels;
remoteObject.addEventListener(FaultEvent.FAULT, onRemoteServiceFault);
remoteObject.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onRemoteServiceFault);
return remoteObject;
}
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
_service = initializeService();
}
public function getUser(event:MouseEvent):void
{
var operation:AbstractOperation = _service.getOperation('get_user');
operation.addEventListener(ResultEvent.RESULT, resultHandler);
operation.send("lisa");
}
protected function resultHandler(event:ResultEvent):void
{
Alert.show(event.result.email+"");
/* var usr:User = event.result as User;
if (usr)
{
txtUserInfo.text = "User: " + usr.username +
"\nEmail: " + usr.email + "\n";
}
else
{
txtUserInfo.text = event.result.toString();
}*/
}
private function onRemoteServiceFault(event:FaultEvent):void
{
var errorMsg:String = "Service error:\n" + event.fault.faultCode;
Alert.show(event.fault.faultDetail, errorMsg);
}
private function onRemoteServiceSecurityError(event:SecurityErrorEvent):void
{
var errorMsg:String = "Service security error";
Alert.show(event.text, errorMsg);
}
]]>
</fx:Script>
<mx:Button label="Get User" click="getUser(event)" />
</s:Application>