WSGI原理:
WSGI(Web Server Gateway Interface,Web 服务器网关接口)则是Python语言中所定义的Web服务器和Web应用程序之间或框架之间的通用接口标准。
WSGI就是一座桥梁,桥梁的一端称为服务端或网关端,另一端称为应用端或者框架端,WSGI的作用就是在协议之间进行转化。WSGI将Web组件分成了三类:Web 服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。
Web Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将响应返回给客户端。
Web应用的本质:
浏览器发送HTTP请求
服务器接收到请求,生成HTML文档
服务器把HTML文档作为HTTP响应的Body发送给浏览器
浏览器收到HTTP响应,从HTTP Body取出HTML文档进行显示
如下是利用socket编程实现的WebServer,代码如下:
主程序文件application.py
import socket
import threading
from response import HttpResponse
from request import HttpRequest
# WSGI服务器
class WSGIServer():
def __init__(self, host='localhost', port=8080, connectSize=100):
'''
:param port: 服务器的端口号
:param connectSize: 默认的并发数量
'''
self.__host = host
self.__port = port
self.__connectSize = connectSize
pass
def startServer(self):
'''
服务启动主程序
:return:
'''
server = None
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((self.__host, self.__port))
server.listen(self.__connectSize)
while True:
print("======服务器启动成功:http://" + self.__host + ":" + str(self.__port))
clientConn, clientAddr = server.accept() # 等待客户端请求
# 启动独立的线程,处理每一次用户请求
wt = WorkThread(clientConn, clientAddr)
wt.start()
pass
except socket.gaierror as g:
print(g)
finally:
if server:
server.close()
pass
pass
class WorkThread(threading.Thread):
def __init__(self, connection, addr, bufferSize=8096):
threading.Thread.__init__(self)
self.__connection = connection
self.__addr = addr
self.__bufferSize = bufferSize
pass
def run(self):
receiveMsg = self.__connection.recv(self.__bufferSize)
receiveMsg = receiveMsg.decode("utf-8")
print(receiveMsg)
request = HttpRequest()
params = request.parseRequest(receiveMsg)
responseText = ""
response = HttpResponse()
if params['Accept'].find('text/html') >=0:
url = 'templates/index.html'
if params['url'] == "/":
url = 'templates/index.html'
elif params['url'] =='/main.html' or params['url'] =='/index.html':
url = 'templates' + params['url']
if params['url'] == '/main.html':
if params.get('dataparams').get('userName') != 'zhangsan':
url = 'templates/index.html'
responseText = response.responseHeader('text/html', 200) + "\n" + response.responseBodyText(url)
pass
pass
pass
responseText = response.responseHeader('text/html', 200) + "\n" + response.responseBodyText(url)
self.__connection.send(responseText.encode("utf-8"))
pass
elif params['Accept'].find('image/') >= 0:
url = params['url']
self.__connection.send(response.responseHeader('image/', 200).encode("utf-8"))
self.__connection.send("\n".encode("utf-8"))
self.__connection.send(response.responseBodyBinary(url[1:]))
pass
print(responseText)
self.__connection.close()
pass
pass
request.py请求文件代码如下
class HttpRequest():
def parseRequest(self, requestText):
params = {}
lineArray = requestText.split('\r\n')
row = 1
isBody = False
bodyText = ""
for line in lineArray:
if row == 1 :
array = line.split(' ')
params['method'] = array[0]
params['url'] = array[1]
params['httptype'] = array[2]
row += 1
elif line.strip() == "":
isBody = True
elif not isBody:
array = line.split(':')
params[array[0]] = line[len(array[0])+2:]
pass
elif isBody:
bodyText += line
pass
params['body'] = bodyText
dataParams = {}
bodyText = bodyText.strip()
if params.get('Content-Type') == 'application/x-www-form-urlencoded' and params['method'] == 'POST':
array = bodyText.split('&')
for data in array:
keyvalue = data.split("=")
dataParams[keyvalue[0]] = keyvalue[1]
pass
pass
params['dataparams'] = dataParams
return params
pass
pass
response.py应答文件代码如下
class HttpResponse():
def responseHeader(self, contentType, ressponseCode):
ressponseCodes = str(ressponseCode)
header = "http/1.1 "+ ressponseCodes +" OK\r\n"
if contentType == 'text/html':
header += "Content-Type: text/html\r\n" + \
"X-Ua-Compatible: IE=Edge,chrome=1\r\n"
elif contentType == "image/":
header += "Content-Type: image/png\r\n" + \
"X-Ua-Compatible: IE=Edge,chrome=1\r\n"
return header
pass
def responseBodyText(self, url):
body = ""
with open(url, 'r') as fp:
body = fp.read()
return body
pass
def responseBodyBinary(self, url):
body = b""
with open(url, 'rb') as fp:
body = fp.read()
return body
pass
runserver.py启动程序文件
from application import WSGIServer
if __name__ == '__main__':
# 创建服务器对象
wsgiServer = WSGIServer()
wsgiServer.startServer()
pass
以上就是本篇文章的全部内容!!!