浅尝WSGI
2009 11 13 07:34 PM 2759次查看
这个协议实际上很简单,就是建立一个服务器,这个服务器接收一个callable的对象application。
每当有访问,服务器就将环境变量environ和输出header所用的start_response函数传给application。
而application需要从environ里找出访问参数,用start_response输出header,并返回一个iterable的对象。
服务器接收到这个对象后,就会将它输出给访问者。
一个最简单的例子如下:
from wsgiref.simple_server import make_server
def application(environ, start_response):
status = '200 OK'
response_headers = [('Content-type','text/plain')]
start_response(status, response_headers)
return ['Hello']
httpd = make_server('', 80, application)
httpd.serve_forever()
运行这个例子,然后访问http://localhost/,就会收到看到'Hello'了。当然也可以实现一个稍微复杂点的例子:
from wsgiref.simple_server import make_server
class application(object):
def __call__(self, environ, start_response):
start_response('200 OK', [('Content-type','text/plain')])
return self.response(environ)
def response(self, environ):
for k, v in environ.iteritems():
yield '%s: %s\n' % (k, v)
make_server('', 80, application()).serve_forever()
我将application改成了一个实现了__call__()的对象,然后返回一个generator对象。服务器会遍历这个generator对象并输出。(实际上''.join()就可以完成这个任务。)而在GAE上则可以这样:
import wsgiref.handlers
def application(environ, start_response):
start_response('200 OK', [('Content-type','text/plain')])
return ['%s: %s\n' % (k, v) for k, v in environ.iteritems()]
def main():
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
可以看出,WSGI是很随意的,所以很多web框架都支持WSGI协议。此外还有一点需要注意,字符串也是iterable对象,但最好别直接返回字符串,将其放在列表或元组中是更有效率的方法。
经我测试,使用yeild生成是最快的,但不能清空;调用列表的append()方法次之;最慢的是使用cStringIO(cStringIO在GAE上是可用的,速度比StringIO约快3倍)。
0条评论 你不来一发么↓