開始研究pyamf的用處了。
pyamf(http://www.pyamf.org)是一個(gè)很好的amf中間件,能跟django, twisted, google app
engine等流行框架整合。現(xiàn)在我要做的就是pyamf結(jié)合django 1.0。據(jù)說flex通過amf做PRC調(diào)用似乎節(jié)省掉很多帶寬。
下載
去官網(wǎng)找到svn地址,checkout下來之后install,很簡單。python真是一種很簡潔很強(qiáng)大的語言,和flex很配啊。
處理機(jī)制
既然跟django結(jié)合,就應(yīng)該有一套處理request,response的機(jī)制。pyamf里對(duì)應(yīng)的就是
pyamf.remoting.gateway.django模塊。打開能看到有一個(gè)類class
DjangoGateway(gateway.BaseGateway),它就是整個(gè)處理流程的主干。class
document很好的解釋了它在django中的用法。僅僅需要在views.py中建立一個(gè)DjangoGateway實(shí)例,這個(gè)實(shí)例是urlmap
對(duì)應(yīng)的處理函數(shù),它把從django底層傳遞過來的request(其實(shí)是AMF編碼過的)解碼,并映射相應(yīng)的python對(duì)象,然后執(zhí)行注冊(cè)的RPC方
法(就是flex調(diào)用amf過程中看到的方法調(diào)用)返回一個(gè)response,最后用AMF機(jī)制編碼這個(gè)response,返回給django。這樣
django再通過層層處理返回這個(gè)AMF信息給flex。如此便是一個(gè)完整的amf
PRC調(diào)用過程。很多的server基本上都是基于類似的機(jī)制,通過中間件層層過濾request和response,達(dá)到隔離底層處理的目的。最后我們
能看到,django內(nèi)部處理amf的調(diào)用是如此之簡單。
DjangoGateway有兩個(gè)方法很重要,一個(gè)是__call__(python的特殊名字方法,自己定義的方法不能用這些名字哦,__call__
使得對(duì)象能像方法那樣用,比如有對(duì)象a,執(zhí)行a()相當(dāng)于執(zhí)行a.__call__()。也許可以猜到了,沒錯(cuò),在django里urlmap需要有一個(gè)
對(duì)應(yīng)的處理函數(shù),__call__就是起這個(gè)處理函數(shù)的作用)。還有一個(gè)就是getResponse方法。它的作用是處理解碼后的request,這是一
些很普通的方法調(diào)用,因?yàn)閞equest已經(jīng)AMF解碼了,它會(huì)尋找合適的PRC方法(選擇的依據(jù)就是AMF指定的方法名,也就是flex調(diào)用amf
url時(shí)的方法名)來處理request。我把這兩個(gè)方法貼上來了。里面重點(diǎn)扯了一下__call__加深印象。
def getResponse(self, http_request, request):
"""
Processes the AMF request, returning an AMF response.
@param http_request: The underlying HTTP Request.
[...]
以下示例使用的Django和PyAMF版本是從SVN下載的最新版本,版本號(hào)分別是:9084和1699。
Django的安裝和配置可以從前面的文章找到,PyAMF的安裝也是很簡單:sudo python setup.py install。
首先在urls.py中增加一行:
(r^'gateway$', 'project.application.amfgateway.gw'),
在application的目錄下創(chuàng)建afmgateway.py:
#coding=utf-8
from pyamf.remoting.gateway.django import DjangoGateway
import project.application.views as views
services = {
'echo' = views.echo,
}
gw = DjangoGateway(services)
在views.py文件增加如下函數(shù):
def echo(request, data):
return data
在Flex里面連接的辦法很普通:
var gateway : NetConnection = new NetConnection();
gateway.connect("http://yousite/gateway");
var resonder : Responder = new Responder(onResult, onFault);
gateway.call("echo", responder, "hello");
其實(shí)一切都很簡單吧,我調(diào)試的時(shí)候卻費(fèi)了好多時(shí)間,只是在urls.py的映射中寫成了
r^'gateway/$'