flex通過PyAmf調用python服務

例子摘自官方文檔:

這是服務端代碼: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>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章