欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

记一次WSGI入门学习

程序员文章站 2022-03-23 18:23:50
...

WSIG

介绍

WSGI全称:web server gateway interface,web服务器的网关接口,是web底层和app之间的解耦的协议,耦合度:大致来说,就是彼此之间的联系。类似于一种通信协议把,起到了一种桥梁的作用。比如,web server和app(flask等)。

工作流程

记一次WSGI入门学习
1、服务器web server :
服务器接受到客户端发来的request之后,提供自己的环境变量还有request(请求方法,url,内容)给app
2、app(application)就是web框架
app里面形成一个回调函数start_response供WSGI调用,参数为environ,start_response
今天看源码发现,这句话是不对的,是WSGI里面生成好环境,还有start_response,供app调用
下面这张流程图是对的
记一次WSGI入门学习

简易实现

  • app应用程序端
def application(environ, start_response):
    print(environ['PATH_INFO'])
    status = '200 OK'
    response_header = [('Content-Type', 'text/html')]
    start_response(status, response_header)
    return ['your path is :{}'.format(environ['PATH_INFO']).encode('utf-8')]
  • 服务器端
from wsgiref.simple_server import make_server
from WSGI简单例子.hello import application

httpd = make_server('', 8000, application)
httpd.serve_forever()
  • 细节解释:
    首先是这边的encode(‘utf-8’),这里必须是byte类型,所以直接用字符串会报错,因为用了format的原因,我们在后面用上utf-8进行编码,另外返回的必须是一个iterable可迭代的,所以这就是为什么要用列表,用yield也是可以的

结果:

记一次WSGI入门学习

用装饰器实现一下路由的过程

前景:

之前一直对路由的工作很是不解,今天遇到了WSGI很巧,正好学了一下。

from wsgiref.simple_server import make_server


class Router:
    def __init__(self):
        self.routes = {}

    def route(self, path):
        def decorator(func):
            self.routes[path] = func
            func()
        return decorator

    def __call__(self, env, start_response):
        path = env['PATH_INFO']
        if path in self.routes:
            status = '200 OK'
            response_header = [('Content-Type', 'text/html')]
            start_response(status, response_header)
            return self.routes[path]()
        else:
            status = '404 Not Found'
            response_header = [('Content-Type', 'text/html')]
            start_response(status, response_header)
            return [b'Not find the source']


app = Router()


@app.route('/')
def index():
    yield 'this is the index'.encode('utf-8')


@app.route('/home')
def home():
    yield b'this is the home'


server = make_server('', 8000, app)
server.serve_forever()

实验结果

记一次WSGI入门学习
记一次WSGI入门学习
记一次WSGI入门学习

总结一下:

我们可以看到,实现一个路由控制还是挺简单的,当然实际当中肯定比我现在做到要复杂。明显的一个弱势就是,头部信息里面的内容怎么处理。

  • 视图函数的返回值是可迭代的,然而我之前,直接用的return 似乎也行,可能是内部代码进行了转换之类的把

  • _call_这个方法,将类的对象成为一个可以被调用的对象,正如里面的make_server(”, 8000, app)

  • 这让我联想到了app.run()这个函数,似乎调用了werkzeug,说不定这也是一种WSGI的实现,值得去看一下,留个坑
    PS:linux 查看某个端口占用

lsof -i:xxx
  • 另一个感悟就是,虽然说读源码能够真正的理解,但是对于我新手来说,显然这并不是一个好的选择,也许先知道 些流程是不错的选择。看些大概的源码,不用那么细致。自己实现框架里面的小处理不失为一种好的选择
相关标签: WSGI