• 什么是Web服务器 什么是WSGI及具体实现例子


    以Flask为例:源码解析(一):WSGI   转自:https://www.csdn.net/tags/MtTaEgzsNTYyNzcyLWJsb2cO0O0O.html
    2022-03-26 18:35:03

    要理解 Flask 的源码,必须有一定的 Python 基础,要熟悉 decorator、magic method、iterator、generator 的概念和用法。还有一点是必须理解 WSGI,下面就讲解一些和 WSGI 相关的概念以及用一些代码来帮助理解 WSGI。

    什么是Web服务器

    Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以处理浏览器等Web客户端的请求并返回相应响应,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个Web服务器是Apache、 Nginx 、IIS。

    什么是WSGI(协议规范)

    Web服务器网关接口(Web Server Gateway Interface),是为了让Web服务器与Python程序或框架能够进行数据交流而定义的接口规范。也就是说,只要Web服务器和Web应用都遵守WSGI协议,那么Web服务器和Web应用就可以随意的组合。

    WSGI应用(实现wsgi协议的实例)

    根据WSGI的规定,Web应用(或被称为WSGI应用)必须是一个可调用对象(callable object),且要满足以下三个条件:

    1. 接受environ和start_response两个参数
    2. 内部调用start_response函数来生成状态码和响应头
    3. 返回一个可迭代的响应体

    用函数实现一个WSGI应用

    def application(environ, start_response):
        """
            environ:包含了请求的所有信息的字典。
            start_response:用来发起响应的函数,参数是状态码、响应头。
    	"""
        start_response('200 OK', [('Content-Type', 'text/plain')])
        yield b'Hello, World!\n'
    

    用类实现一个WSGI应用

    class AppClass:
        def __init__(self, environ, start_response):
            self.environ = environ
            self.start_response= start_response
    
        def __iter__(self):
            self.start_response('200 OK', [('Content-Type', 'text/plain')])
            yield b'Hello, World!\n'
    

    Flask的WSGI实现

    class Flask(_PackageBoundObject):
    	def wsgi_app(self, environ, start_response):
            ...
             
    	def __call__(self, environ, start_response):
            """Shortcut for :attr:`wsgi_app`."""
            return self.wsgi_app(environ, start_response)
    

    WSGI服务器

    简单实现一个WSGI服务器(仅用于理解)

    from io import BytesIO
    
    def call_application(app, environ):
        status = None
        headers = None
        body = BytesIO()
        
        def start_response(rstatus, rheaders):
            nonlocal status, headers
            status, headers = rstatus, rheaders
            
        app_iter = app(environ, start_response)
        try:
            for data in app_iter:
                assert status is not None and headers is not None, \
                    "start_response() was not called"
                body.write(data)
        finally:
            if hasattr(app_iter, 'close'):
                app_iter.close()
        return status, headers, body.getvalue()
    
    environ = {...}
    status, headers, body = call_application(app, environ)
    

    使用Python内置模块wsgiref的WSGI服务器

    from wsgiref.simple_server import make_server
    
    def wsgi_app(environ, start_response):
        ...
    
    server = make_server('0.0.0.0', 5000, wsgi_app)
    server.serve_forever()
    

    使用WerkZeug模块的WSGI服务器

    用flask run命令运行时,实际上是在运行Werkzeug实现的WSGI服务器

    from werkzeug.serving import run_simple
    
    def wsgi_app(environ, start_response):
        ...
        
    run_simple('0.0.0.0', 5000, wsgi_app)
    

    参考

    WEB服务器_百度百科 (baidu.com)
    Web Server Gateway Interface - Wikipedia

  • 相关阅读:
    毕设计划(一)
    上传整个项目或者文件夹到github
    分布式架构中数据一致性常见的几个问题(云时代架构文章读后感16)
    关于技术规划、管理、架构的思考(云时代架构文章读后感15)
    互联网高新吗(云时代架构文章读后感14)
    第三方支付账务系统设计难点(云时代架构文章读后感13)
    关于SOA的理解
    系统架构师(云时代架构文章读后感12)
    会话管理(云时代架构文章读后感11)
    【sklearn第二讲】scikit-learn 方法一览图
  • 原文地址:https://www.cnblogs.com/changbaishan/p/16277956.html
Copyright © 2020-2023  润新知