转载使用PyAmf来实现Flex与Django的通信

时间:2021-02-06 18:55:34

三年前,用过AmfPHP与Flash/Flex Remoting做过交互,最近接触Python,公司项目用的Flex做前端,所以接触了PyAmf。PyAmf本质上跟AmfPHP是雷同的。都是通 过对AMF协议(ActionScript Message Format)协议的支持来实现对Flash的交互过程。

一、首先,简单的介绍一下AMF协议格式。
AMF是Adobe独家开发出来的通信协议,它采用二进制压缩,序列化、反序列化、传输数据,从而为Flash 播放器与Flash Remoting网关通信提供了一种轻量级的、高效能的通信方式。AMF最大的特色在于可直接将Flash内置对象,例如Object, Array, Date, XML,传回服务器端,并且在服务器端自动进行解析成适当的对象,这就减轻了开发人员繁复工作,同时也更省了开发时间。它采用二进制编码,可以高度压缩数 据,因此非常适合用来传递大量的资料。数据量越大,Flash Remoting的传输效能就越高,远远超过Web Service以及使用纯文本的传输方式的XML。

AMF协议是基于Http协议的,它的处理过程大致如下:
1、从客户端获取Http请求(Request)流。
2、对流进行反序列化(Deserialize),得到服务器端程序能够识别的数据,并建立响应(Response)消息。
3、找到相应的远程服务
4、调用服务器端方法,对流进行各种处理得到返回值。
5、序列化响应流
6、将序列化响应流发送Http响应给客户端。

二、安装配置PyAmf和Django
PyAmf目前的稳定版本是0.3,去官方网站下载压缩包,解压文件,执行python setup.py install 即可完成安装。
至于Django的安装配置,我前面的文章已经讲过了,详细请参阅http://www.kokkowon.cn/archives/33。

下面我们来开发具体的实际应用。首先简单介绍下pyAMF.django的处理机制。
Pyamf通过pyamf.remoting.gateway.django模块来实现与django Request、Response相对应处理机制。其中pyamf.remoting.gateway.django.DjangoGateway类是整 个处理流程的主干。我们仅仅需要在django中建立一个DjangoGateway的实例,这个实例通过urlmap对应到响应的处理函数,将把从底层 传递过来的Request解码,并映射到响应的Python对象,然后执行注册的RPC方法,返回一个Response,然后采用AMF协议格式将 Response编码,返回给django,django通过它本身的相关机制,将这个Response以http响应的方式返回给客户端。

1)创建DjangoGateway
首先创建Django项目,然后创建一个应用程序,我这里还叫做app应用,
django-admin.py startproject fortest
python manage.py startapp app
我前面的文章已经讲过了,详细请参阅http://www.kokkowon.cn/archives/33。

定义数据库模型:
app/models.py用于定义我们的数据库模型,将其修改如下:

  1. """
  2. 数据库模型
  3.  
  4. @see: U{Django homepage (external)<http://djangoproject.com>}
  5. @author: U{kokko won<kokko313@gmail.com>}
  6. @since: 0.1.0
  7. """
  8. from   django . db import models
  9. import   datetime
  10.  
  11. #Mysql Text类型
  12. class   MysqlTextField ( models . Field ) :
  13.     def   db_type ( self ) :
  14.         return   ' text '
  15.  
  16. class   Favorite :
  17.     TYPE_CHOICES = (
  18.         ( ' url ' , ' 网址 ' ) ,
  19.         ( ' music ' , ' 音频 ' ) ,
  20.         ( ' video ' , ' 视频 ' ) ,
  21.     )
  22.     type = models . CharField ( ' 类型 ' , max_length = 30 , db_index = True , choices = TYPE_CHOICES )
  23.     title = models . CharField ( ' 标题 ' , max_length = 250 )
  24.     body   = models . CharField ( ' 内容 ' , default = '' , max_length = 255 )
  25.     general = MysqlTextField ( ' 描述 ' , default = '' , blank = True )
  26.     created = models . DateTimeField ( ' 添加时间 ' , default = datetime . datetime . now , blank = True )
  27.  
  28.     def   __unicode__ ( self ) :
  29.         return   self . title
  30.  
  31. class   UserFavorite ( Favorite , models . Model ) :
  32.     user_id = models . CharField ( ' 用户ID ' , max_length = 250 , db_index = True )
  33.     type = Favorite . type
  34.     title = Favorite . title
  35.     body = Favorite . body
  36.     general = Favorite . general
  37.     created = Favorite . created
  38.    
  39.     class   Meta :
  40.         db_table = ' user_favorites '
  41.         verbose_name = ' 用户收藏夹 '
  42.         verbose_name_plural = ' 用户收藏夹列表 '

以上定义了一个叫做user_favorites的表。关于Django里面model的定义说明请查看这里:http://docs.djangoproject.com/en/dev/

接着在settings.py中激活我们的app应用(应用名称为:fortest.users),将其中的INSTALLED_APPS修改如下:

  1. INSTALLED_APPS = (
  2.     ' django.contrib.auth ' ,
  3.     ' django.contrib.contenttypes ' ,
  4.     ' django.contrib.sessions ' ,
  5.     ' django.contrib.sites ' ,
  6.     ' fortest.app ' ,
  7. )

配置数据库,修改settings.py中的:

  1. DATABASE_ENGINE = ' mysql '            # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
  2. DATABASE_NAME = ' test '              # Or path to database file if using sqlite3.
  3. DATABASE_USER = ' root '              # Not used with sqlite3.
  4. DATABASE_PASSWORD = ''          # Not used with sqlite3.
  5. DATABASE_HOST = ''              # Set to empty string for localhost. Not used with sqlite3.
  6. DATABASE_PORT = ''              # Set to empty string for default. Not used with sqlite3.

返回到工程根目录,执行以下命令,自动创建表结构:
python manage.py syncdb
django会自动在test数据库中创建user_favorites表。

初始数据的写入
现在我们可以利用Django提供的API来方便的写入我们的一些初始数据。
运行以下命令,进入交互的Python Shell:
python manage.py shell
执行如下脚本

  1. #导入我们前面定义的model类
  2. >>> from   fortest . app . models import UserFavorite
  3. #创建新记录
  4. >>> uf = UserFavorite ( user_id = ' kokko ' , type = 1 , title = ' fortest ' , body = ' http:// ' , general = ' none thing ' )
  5. >>> uf . save ()
  6. #...依次导入多条数据
  7. #取出所有用户的收藏数据
  8. >>> UserFavorite . objects . all ()
  9. [ < UserFavorite : 163 >, < UserFavorite : sohu >, < UserFavorite : 163 >, < UserFavorite :
  10. 163 >, < UserFavorite : 163 >,< UserFavorite : fortest > ]

更多的Django API信息请查看http://docs.djangoproject.com/en/dev/

接着在我们的Django工程目录下(app目录下)创建一个amfgateway.py文件,内容如下:

  1. from pyamf . remoting . gateway . django import DjangoGateway
  2. from   models import UserFavorite
  3.  
  4. """
  5. save用户收藏
  6. """
  7. def   save_user_favorite ( id , user_id , _type , _title , _body , general = '' ) :
  8.     if   id == 0 :
  9.         userFavorite = UserFavorite ( user_id = user_id , type = _type , title = _title , body = _body , general = general )
  10.     else :
  11.         userFavorite = UserFavorite ( id = id , user_id = user_id , type = _type , title = _title , body = _body , general = general )
  12.     userFavorite . save ()
  13.     return   userFavorite
  14.  
  15. """
  16. 添加用户收藏
  17. """
  18. def   add_user_favorite ( request , user_id , _type , _title , _body , general = '' ) :
  19.     return   save_user_favorite ( 0 , user_id , _type , _title , _body , general )
  20.  
  21. """
  22. 修改用户收藏
  23. """
  24. def   edit_user_favorite ( request , id , user_id , _type , _title , _body , general = '' ) :
  25.     return   save_user_favorite ( id , user_id , _type , _title , _body , general )
  26.  
  27. """
  28. 用户收藏夹列表
  29. """
  30. def   user_favorite ( request , field = '' , value = '' ) :
  31.     if   field == ' type ' :
  32.         rs = UserFavorite . objects . filter ( type = value )
  33.     elif   field == ' user_id ' :
  34.         rs = UserFavorite . objects . filter ( user_id = value )
  35.     else :
  36.         rs = UserFavorite . objects . all ()        
  37.     return   rs
  38.  
  39.  
  40. """
  41. 注册App网关
  42. """
  43. appGateway = DjangoGateway ( {
  44.     ' adduserfavorite ' : add_user_favorite ,
  45.     ' edituserfavorite ' : edit_user_favorite ,
  46.     ' userfavorite ' : user_favorite
  47. } )

打开$work_root/fortest/urls.py,添加(r’^app/gateway/’, ‘fortest.app.amfgateway.appGateway’),以定义AMF网关的访问URL,用于Flex端访问。示例配置如下:

  1. # coding: utf-8
  2. from   django . conf . urls . defaults import *
  3.  
  4. # Uncomment the next two lines to enable the admin:
  5. from   django . contrib import admin
  6. admin . autodiscover ()
  7.  
  8. urlpatterns = patterns ( '' ,
  9.     # Example:
  10.     # (r'^fortest/', include('fortest.foo.urls')),
  11.     ( r ' ^$ ' , ' fortest.app.views.index ' ) ,
  12.     ( r ' ^app/ ' , include ( ' fortest.app.urls ' )) ,
  13.     ##这里是新添加的配置
  14.     ( r ' ^app/gateway/ ' , ' fortest.app.amfgateway.appGateway ' ) ,
  15.  
  16.     # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
  17.     # to INSTALLED_APPS to enable admin documentation:
  18.     # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
  19.  
  20.     # Uncomment the next line to enable the admin:
  21.     ( r ' ^admin/(.*) ' , admin . site . root ) ,
  22. )

至此,终于告一段落了,接下来就是对应用进行测试了。

2)测试PyAmf
在fortest目录下,新建c.py

  1. from pyamf . remoting . client import RemotingService
  2. import   sys
  3.  
  4. gateway = RemotingService ( ' http://localhost:8000/app/gateway/ ' )
  5. adduserfavorite_service = gateway . getService ( ' adduserfavorite ' )
  6. edituserfavorite_service = gateway . getService ( ' edituserfavorite ' )
  7. userfavorite_service = gateway . getService ( ' userfavorite ' )
  8.  
  9. """
  10. #添加用户收藏
  11. """
  12. rs = adduserfavorite_service ( ' kokko ' , ' 网址 ' , ' 163 ' , ' http://www.163.com ' )
  13. print   rs [ ' id ' ]
  14. print   " ---------------------------- "
  15. #编辑用户收藏
  16. rs = edituserfavorite_service ( 2 , ' wwq ' , ' 视频 ' , ' sohu ' , ' http://www.sohu.com ' )
  17. print   rs
  18. print   " ---------------------------- "
  19. #用户收藏列表
  20. rs = userfavorite_service ( ' user_id ' , ' kokko ' )
  21. for   _item in rs :
  22.     print   _item . title + '         ' + _item . type + '         ' + _item . user_id + '         ' + _item . body
  23. print   " ---------------------------- "
  24. sys . exit ( 0 )

运行服务器:manage.py runserver
运行测试程序:python c.py 将显示响应结果,如下图示例:
转载使用PyAmf来实现Flex与Django的通信


转载使用PyAmf来实现Flex与Django的通信
证明测试完全通过,flex端可以使用相关接口和服务器进行通讯了。由于时间关系,我这里不再给出Flash端的实例,等有时间再行补上。
参考
http://pyamf.org/
http://wiki.woodpecker.org.cn/moin/NewEdit
http://www.donews.net/limodou
http://blog.eshangrao.com/2008/02/16/447/