首页 技术 正文
技术 2022年11月19日
0 收藏 335 点赞 4,317 浏览 4149 个字

感觉WSGI确实和SERVLET相似,为PYTHON提供了运行和管理环境。WSGI服务器和PYTHON的WEB框架一起,实现WEB响应。

步骤:

  • 首先,服务器启动并加载一个由Web框架/应用提供的可调用的’application’
  • 然后,服务器读取请求
  • 然后,服务器解析它
  • 然后,服务器使用请求的数据创建了一个’environ’字典
  • 然后,服务器使用’environ’字典和’start_response’做为参数调用’application’,并拿到返回的响应体。
  • 然后,服务器使用调用’application’返回的数据,由’start_response’设置的状态和响应头,来构造HTTP响应。
  • 最终,服务器把HTTP响应传回给户端。

代码(别小看它,启动DJANGO的APP都可以的,但DJANGO必须提供一个WSGI供它调用APP):

# Testedimport socketimport StringIOimport sysclass WSGIServer(object):    address_family = socket.AF_INET    socket_type = socket.SOCK_STREAM    request_queue_size = 1    def __init__(self, server_address):        # Create a listening socket        self.listen_socket = listen_socket = socket.socket(            self.address_family,            self.socket_type        )        # Allow to reuse the same address        listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)        # Bind        listen_socket.bind(server_address)        # Activate        listen_socket.listen(self.request_queue_size)        # Get server host name and port        host, port = self.listen_socket.getsockname()[:2]        self.server_name = socket.getfqdn(host)        self.server_port = port        # Return headers set by Web framework/Web application        self.headers_set = []    def set_app(self, application):        self.application = application    def serve_forever(self):        listen_socket = self.listen_socket        while True:            # New client connection            self.client_connection, client_address = listen_socket.accept()            # Handle one request and close the client connection. Then            # loop over to wait for another client connection            self.handle_one_request()    def handle_one_request(self):        self.request_data = request_data = self.client_connection.recv(1024)        # Print formatted request data a la 'curl -v'        print(''.join(            '> {line}n'.format(line=line)            for line in request_data.splitlines()        ))        self.parse_request(request_data)        # Construct environment dictionary using request data        env = self.get_environ()        # It's time to call our application callable and get        # back a result that will become HTTP response body        result = self.application(env, self.start_response)        # Construct a response and send it back to the client        self.finish_response(result)    def parse_request(self, text):        request_line = text.splitlines()[0]        request_line = request_line.rstrip('rn')        # Break down the request line into components        (self.request_method,  # GET         self.path,            # /hello         self.request_version  # HTTP/1.1         ) = request_line.split()    def get_environ(self):        env = {}        # The following code snippet does not follow PEP8 conventions        # but it's formatted the way it is for demonstration purposes        # to emphasize the required variables and their values        #        # Required WSGI variables        env['wsgi.version']      = (1, 0)        env['wsgi.url_scheme']   = 'http'        env['wsgi.input']        = StringIO.StringIO(self.request_data)        env['wsgi.errors']       = sys.stderr        env['wsgi.multithread']  = False        env['wsgi.multiprocess'] = False        env['wsgi.run_once']     = False        # Required CGI variables        env['REQUEST_METHOD']    = self.request_method    # GET        env['PATH_INFO']         = self.path              # /hello        env['SERVER_NAME']       = self.server_name       # localhost        env[        return env    def start_response(self, status, response_headers, exc_info=None):        # Add necessary server headers        server_headers = [            ('Date', 'Tue, 31 Mar 2015 12:54:48 GMT'),            ('Server', 'WSGIServer 0.2'),        ]        self.headers_set = [status, response_headers + server_headers]        # To adhere to WSGI specification the start_response must return        # a 'write' callable. We simplicity's sake we'll ignore that detail        # for now.        # return self.finish_response    def finish_response(self, result):        try:            status, response_headers = self.headers_set            response = 'HTTP/1.1 {status}rn'.format(status=status)            for header in response_headers:                response += '{0}: {1}rn'.format(*header)            response += 'rn'            for data in result:                response += data            # Print formatted response data a la 'curl -v'            print(''.join(                '&gt; {line}n'.format(line=line)                for line in response.splitlines()            ))            self.client_connection.sendall(response)        finally:            self.client_connection.close()SERVER_ADDRESS = (HOST, PORT) = '', 8888def make_server(server_address, application):    server = WSGIServer(server_address)    server.set_app(application)    return serverif __name__ == '__main__':    if len(sys.argv) < 2:        sys.exit('Provide a WSGI application object as module:callable')    app_path = sys.argv[1]    module, application = app_path.split(':')    module = __import__(module)    application = getattr(module, application)    httpd = make_server(SERVER_ADDRESS, application)    print('WSGIServer: Serving HTTP on port {port} ...n'.format(port=PORT))    httpd.serve_forever()
def app(environ, start_response):    status = '200 OK'    response_headers = [('Content-Type', 'text/plain')]    start_response(status, response_headers)    return ['Hello world from a simple WSGI application!n']

截图:

深入WSGI,并按样例实现一个

深入WSGI,并按样例实现一个

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,985
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,501
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,345
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,128
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,763
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,840