flask默認的wsgi引用自wekurgflask
聲明app:FLASK對象服務器
app.run()app
run_simple(host, port, self, **options)socket
引用自werkzurg.servingide
host 主機函數
port 監聽端口post
self app自己this
run_simple(host, port, self, **options)spa
host 主機server
port 監聽端口
self app自己
run_simple引用inner()
作了兩件事,聲明srv,運行它
srv = make_server(hostname, port, application, threaded,
processes, request_handler,
passthrough_errors, ssl_context,
fd=fd)
if fd is None:
srv.serve_forever()
看一下make_server()
它最終執行return BaseWSGIServer(host, port, app, request_handler,
passthrough_errors, ssl_context, fd=fd)
那麼
srv = BaseWSGIServer()
class BaseWSGIServer(HTTPServer, object):
"""Simple single-threaded, single-process WSGI server."""
是默認的server是BaseWSGIServer()
初始化中執行了
HTTPServer.__init__(self, get_sockaddr(host, int(port),self.address_family), handler)
在這一過程當中
建立socket,綁定,listen
核心屬性釋義:
self.socket
host,
port
self.server_address = server_address = get_sockaddr(host, int(port),self.address_family)
self.RequestHandlerClass = WSGIRequestHandler
至此,server對象建立完成並對端口進行監聽。
中間還有一些上下文,ssl等處理,略過。
下面的通常就是構建一個死循環,處理請求,等待。。。
上面BaseWSGIServer()已初始化完成,返回flask調用serve_forever
它實質是調用httpserver.serve_forever(self)
先看下BaseWSGIServer()
BaseWSGIServer():
def serve_forever(self):
self.shutdown_signal = False
try:
HTTPServer.serve_forever(self)
except KeyboardInterrupt:
pass
finally:
self.server_close()
繼續向下,HTTPServer:
import socketserver
from http.server import HTTPServer, BaseHTTPRequestHandler
它基本繼承於socketserver.TCPServer
class HTTPServer(socketserver.TCPServer):
socketserver.TCPServer基本繼承於BaseServer
class TCPServer(BaseServer):
找到serve_forever
def serve_forever(self, poll_interval=0.5):
"""Handle one request at a time until shutdown.
Polls for shutdown every poll_interval seconds. Ignores
self.timeout. If you need to do periodic tasks, do them in
another thread.
"""
self.__is_shut_down.clear()
try:
# XXX: Consider using another file descriptor or connecting to the
# socket to wake this up instead of polling. Polling reduces our
# responsiveness to a shutdown request and wastes cpu at all other
# times.
with _ServerSelector() as selector:
selector.register(self, selectors.EVENT_READ)
while not self.__shutdown_request:
ready = selector.select(poll_interval)
if ready:
self._handle_request_noblock()
self.service_actions()
finally:
self.__shutdown_request = False
self.__is_shut_down.set()
作了如下事情:
selector.register(self, selectors.EVENT_READ)
ready = selector.select(poll_interval)
if ready:
self._handle_request_noblock()
至此,服務算是跑起來了。
從socket開始,上面講過觸發監聽後調用BaseWSGIServer() 的self._handle_request_noblock()
def _handle_request_noblock(self):
"""Handle one request, without blocking.
I assume that selector.select() has returned that the socket is
readable before this function was called, so there should be no risk of
blocking in get_request().
"""
try:
request, client_address = self.get_request()
# get_request實質是con, addr = self.socket.accept()
except OSError:
return
if self.verify_request(request, client_address):
try:
self.process_request(request, client_address)
except Exception:
self.handle_error(request, client_address)
self.shutdown_request(request)
except:
self.shutdown_request(request)
raise
else:
self.shutdown_request(request)
核心句是self.process_request(request, client_address)
最終是調用self.RequestHandlerClass(request, client_address, self)
上面講過self.RequestHandlerClass = WSGIRequestHandler
到這裏是監聽到了一個客戶端發起了鏈接,下面進入到鏈接及請示處理。
先看下定義及初始化
class WSGIRequestHandler(BaseHTTPRequestHandler, object):
"""A request handler that implements WSGI dispatching."""
class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
class StreamRequestHandler(BaseRequestHandler):
class BaseRequestHandler:
"""Base class for request handler classes.
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()
鏈條很長,在初始化時執行self.handle()
def handle(self):
"""Handles a request ignoring dropped connections."""
rv = None
try:
rv = BaseHTTPRequestHandler.handle(self)
except (socket.error, socket.timeout) as e:
self.connection_dropped(e)
except Exception:
if self.server.ssl_context is None or not is_ssl_error():
raise
if self.server.shutdown_signal:
self.initiate_shutdown()
return rv
def handle_one_request(self):
"""Handle a single HTTP request."""
self.raw_requestline = self.rfile.readline()
if not self.raw_requestline:
self.close_connection = 1
elif self.parse_request():
return self.run_wsgi()
後面代碼比較長,簡單點說
self.handle_one_request()的任務:
處理本次鏈接,收取報文,把socket recv的數據第一行(請求頭)放到self.raw_requestline
而後調用self.parse_request(),負責把報文解析成http報文,提取出請求方法(get/post)
而後執行self.run_wsgi(),在其中執行下列語句:
self.environ = environ = self.make_environ()
# 生成上下文
最後execute(self.server.app)
# 交由app處理
execute定義:
def execute(app):
application_iter = app(environ, start_response)
try:
for data in application_iter:
write(data)
if not headers_sent:
write(b'')
finally:
if hasattr(application_iter, 'close'):
application_iter.close()
application_iter = None
釋義:application_iter = app(environ, start_response)等於
Flask().__call__(environ, start_response)
而後flask返回數據,wsgi寫入socket。
flask返回數據
核心是上下文,路由,執行view函數
最後由下面一句調用view function
return self.view_functions[rule.endpoint](**req.view_args)
WSGI主要兩個任務:
據此有兩大類class
第一類:服務
class BaseWSGIServer(HTTPServer, object):
class HTTPServer(socketserver.TCPServer):
它基本繼承於socketserver.TCPServer
class TCPServer(BaseServer):
socketserver.TCPServer基本繼承於BaseServer
分別是頂層應用,HTTP,TCP,socket四個層面的功能類。
第二類:請求處理
WSGIRequestHandler
class WSGIRequestHandler(BaseHTTPRequestHandler, object):
"""A request handler that implements WSGI dispatching."""
class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
相似的,分三層,WSGI,HTTP,SOCKET。