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

来源:互联网 发布:淘宝店铺在哪里买 编辑:程序博客网 时间:2024/04/30 06:10

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

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


cpy
证明测试完全通过,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/

原创粉丝点击