博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入WSGI,并按样例实现一个
阅读量:7165 次
发布时间:2019-06-29

本文共 5625 字,大约阅读时间需要 18 分钟。

感觉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 sys class 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['SERVER_PORT']       = str(self.server_port)  # 8888        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(                '> {line}n'.format(line=line)                for line in response.splitlines()            ))            self.client_connection.sendall(response)        finally:            self.client_connection.close() SERVER_ADDRESS = (HOST, PORT) = '', 8888 def make_server(server_address, application):    server = WSGIServer(server_address)    server.set_app(application)    return server if __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']

 

截图:

转载地址:http://bavwm.baihongyu.com/

你可能感兴趣的文章
创高安防与Orange签署战略合作协议
查看>>
Mysql CPU占用高的问题解决方法小结
查看>>
OpenDaylight发布第四版本 推动SDN开源革命
查看>>
图说历届云栖大会精彩内容(长图鉴赏)
查看>>
切换到云思维模式 联想借力SAP实现全球采购转型
查看>>
欧盟批准释放700MHz频段 促进5G发展
查看>>
“打农药”都不省心:勒索病毒冒充王者荣耀外挂
查看>>
XCode 8.0 下 NSLog 打印不完全
查看>>
知乎的乌托邦之梦:“扭曲立场”能否让知识变现
查看>>
Telecity公司在英国数据中心UPS故障导致网络服务中断
查看>>
联想修复茄子快传(SHAREit)安全漏洞
查看>>
盘点:物联网产业的六大特征
查看>>
智慧城市研究述评
查看>>
思科和VMware的SDN解决方案竟可同时选择
查看>>
据实而用 浅析会议摄像机的选购
查看>>
美国会委员会建议禁止中国国企收购美国资产
查看>>
联想走出收购摩托罗拉阴影
查看>>
武汉使用电子标签技术监控餐厨垃圾
查看>>
漳州电信分公司10000号客服中心推出新媒体服务
查看>>
管中窥豹!从电子市场看安防行业的变与不变
查看>>