androider 发表于 2013-1-27 04:45:05

pyAMF.django的处理机制

既然跟django结合,就应该有一套处理request,response的机制。
pyamf里对应的就是 pyamf.remoting.gateway.django模块。打开能看到有一个类class DjangoGateway(gateway.BaseGateway),它就是整个处理流程的主干。仅仅需要在views.py中建立一个DjangoGateway实例,这个实例是urlmap对应的处理函数,它把从django底层传递过来的request(其实是AMF编码过的)解码,并映射相应的python对象,然后执行注册的RPC方法(就是flex调用amf过程中看到的方法调用)返回一个response,最后用AMF机制编码这个response,返回给 django。这样django再通过层层处理返回这个AMF信息给flex。如此便是一个完整的amf PRC调用过程。很多的server基本上都是基于类似的机制,通过中间件层层过滤request和response,达到隔离底层处理的目的。最后我们能看到,django内部处理amf的调用是如此之简单。

DjangoGateway有两个方法很重要,一个是__call__(python的特殊名字方法,自己定义的方法不能用这些名字哦,__call__使得对象能像方法那样用,比如有对象a,执行a()相当于执行a.__call__()。也许可以猜到了,没错,在django里urlmap需要有一个对应的处理函数,__call__就是起这个处理函数的作用)。还有一个就是getResponse方法。它的作用是处理解码后的request,这是一些很普通的方法调用,因为request已经AMF解码了,它会寻找合适的PRC方法(选择的依据就是 AMF指定的方法名,也就是flex调用amf url时的方法名)来处理request。
    def getResponse(self, http_request, request):      """      Processes the AMF request, returning an AMF response.         @param http_request: The underlying HTTP Request.      @type http_request: C{HTTPRequest}      @param request: The AMF Request.      @type request: L{Envelope}      @rtype: L{Envelope}      @return: The AMF Response.      """      response = remoting.Envelope(request.amfVersion, request.clientType)         for name, message in request:            processor = self.getProcessor(message)            response = processor(message, http_request=http_request)         return response   def __call__(self, http_request):      """      Processes and dispatches the request. 解码request,并处理         @param http_request: The C{HTTPRequest} object. 来自django底层的httprequest对象,body还是被AMF编码的      @type http_request: C{HTTPRequest}      @return: The response to the request. 返回一个AMF编码过的response对象      @rtype: C{HTTPResponse}      """      if http_request.method != 'POST':            return http.HttpResponseNotAllowed(['POST'])         context = pyamf.get_context(pyamf.AMF0)      stream = None      http_response = http.HttpResponse()         # Decode the request 解码request对象      try:            request = remoting.decode(http_request.raw_post_data, context)      except pyamf.DecodeError:            self.logger.exception(gateway.format_exception())            http_response.status_code = 400             return http_response         self.logger.debug("AMF Request: %r" % request)         # Process the request 处理request,这里它调用了getResponse,就会按照指定的方法名来正式处理request      try:            response = self.getResponse(http_request, request)      except (KeyboardInterrupt, SystemExit):            raise      except:            self.logger.exception(gateway.format_exception())             return http.HttpResponseServerError()         self.logger.debug("AMF Response: %r" % response)         # Encode the response 编码response,在返回之前要用AMF编码好      try:            stream = remoting.encode(response, context)      except pyamf.EncodeError:            self.logger.exception(gateway.format_exception())             return http.HttpResponseServerError('Unable to encode the response')         buf = stream.getvalue()      http_response['Content-Type'] = remoting.CONTENT_TYPE      http_response['Content-Length'] = str(len(buf))      http_response['Server'] = gateway.SERVER_NAME      http_response.write(buf)         return http_response
页: [1]
查看完整版本: pyAMF.django的处理机制