Python 웹 서버 게이트웨이 인터페이스(또는 줄여서 "wizgy"로 발음하는 WSGI).
WSGI를 사용하면 개발자가 웹 서버에서 선택한 웹 프레임워크를 분리할 수 있습니다. 웹 서버와 웹 프레임워크를 혼합하고 일치시켜 적절한 페어링을 선택할 수 있습니다. 예를 들어 Gunicorn, Nginx/uWSGI 또는 Waitress에서 Django, Flask 또는 Pyramid를 실행할 수 있습니다. 서버와 아키텍처를 모두 지원하는 WSGI 덕분에 진정한 혼합이 가능합니다.
웹 서버에는 WSGI 인터페이스가 있어야 합니다. 모든 최신 Python 웹 프레임워크에는 이미 WSGI 인터페이스가 있으므로 코드를 수정하지 않고도 서버와 기능을 사용할 수 있습니다. . 웹 프레임워크는 함께 작동합니다.
WSGI는 웹 서버에서 지원되며 웹 프레임워크를 사용하면 자신에게 맞는 페어링을 선택할 수 있을 뿐만 아니라 서버와 프레임워크 개발자가 서로 방해하지 않고 선호하는 분야와 전문 지식에 집중할 수 있도록 편의성도 제공합니다. 다른 언어에도 비슷한 인터페이스가 있습니다. Java에는 Servlet API가 있고 Ruby에는 Rack이 있습니다.
WSGI 인터페이스 정의는 매우 간단합니다. 웹 개발자는 HTTP 요청에 응답하는 기능만 구현하면 됩니다. 가장 간단한 "Hello World!" 웹 버전을 살펴보겠습니다.
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')])return 'Hello World!'
위의 application() 함수는 WSGI 표준을 준수하는 HTTP 처리 함수입니다.
environ: 하나는 다음을 포함합니다. all HTTP 요청 정보의 dict 객체
start_response: HTTP 응답을 보내는 함수.
전체 application() 함수 자체는 HTTP를 파싱하는 부분이 없습니다. 즉, 기본 웹 서버 파싱 부분과 애플리케이션 로직 부분이 분리되어 있어 개발자가 한 영역에 집중할 수 있습니다.
The application() 함수는 WSGI 서버에서 호출되어야 합니다. WSGI 사양을 준수하는 서버가 많이 있습니다. 현재 저희 웹서버 프로젝트의 목적은 정적인 웹페이지를 분석하고 동적 웹페이지도 분석할 가능성이 매우 높은 서버를 만드는 것입니다
구현 코드:
import time,multiprocessing,socket,os,reclass MyHttpServer(object):def __init__(self): serveSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.serveSocket = serveSocket self.HTMLPATH = './html'def bind(self,port=8000): self.serveSocket.bind(('',port))def start(self): self.serveSocket.listen()while True: clientSocket, clientAddr = self.serveSocket.accept() print(clientSocket) multiprocessing.Process(target=self.serveHandler, args=(clientSocket, clientAddr)).start() clientSocket.close()def serveHandler(self,clientSocket,clientAddr):try: recvData = clientSocket.recv(1024).decode('gbk') fileName = re.split(r' +', recvData.splitlines()[0])[1] filePath = self.HTMLPATHif fileName.endswith('.py'):try: pyname=fileName[1:-3]# 导入 pyModule = __import__(pyname) env={} responseBody = pyModule.application(env,self.startResponse) responseLine = self.responseLine responseHeader = self.responseHeaderexcept ImportError: responseLine = 'HTTP/1.1 404 NOT FOUND' responseHeader = 'Server: ererbai' + os.linesep responseHeader += 'Date: %s' % time.ctime() responseBody = '<h1>很抱歉,服务器中找不到你想要的内容<h1>'else:if '/'== fileName: filePath += '/index.html'else: filePath += fileNametry: file = None file =open(filePath,'r',encoding='gbk') responseBody = file.read() responseLine = 'HTTP/1.1 200 OK' responseHeader = 'Server: ererbai' + os.linesep responseHeader += 'Date:%s' % time.ctime()except FileNotFoundError: responseLine = 'HTTP/1.1 404 NOT FOUND' responseHeader = 'Server: ererbai' + os.linesep responseHeader += 'Date:%s' % time.ctime() responseBody = '很抱歉,服务器中找不到你想要的内容'finally:if (file!=None) and (not file.closed): file.close()except Exception as ex: responseLine = 'HTTP/1.1 500 ERROR' responseHeader = 'Server: ererbai' + os.linesep responseHeader += 'Date: %s' % time.ctime() responseBody = '服务器正在维护中,请稍后再试。%s'%exfinally: senData = responseLine + os.linesep + responseHeader + os.linesep + os.linesep + responseBody print(senData) senData = senData.encode('gbk') clientSocket.send(senData)if (clientSocket!=None) and ( not clientSocket._closed): clientSocket.close()def startResponse(self,status,responseHeaders): self.responseLine = status self.responseHeader = ''for k,v in responseHeaders: kv = k + ':' + v + os.linesep self.responseHeader += kvif __name__ == '__main__': server = MyHttpServer() server.bind(8000) server.start()
서버에 존재하는 HTML 파일:
index .html
<html><head><title>首页-毕业季</title><meta http-equiv=Content-Type content="text/html;charset=gbk"></head><body>我们仍需共生命的慷慨与繁华相爱,即使岁月以刻薄和荒芜相欺。</body></html>
biye.html
<!DOCTYPE html><html lang="en"><head><meta charset="gbk"><title>毕业季</title></head><body>![](http://localhost:51017/day18/html/biyeji.png)<br>当年以为六月不过也很平常<br>当自己真正经历了毕业<br>才知道偶尔看到六月毕业季等字里所流露的种种想要重温却不敢提及的回忆<br>毕业了<br>那个夏天,我的毕业季,我的青春年少<br>六月<br>有人笑着说解脱,有人哭着说不舍<br>那年,<br>你对我说的你好<br>在不知不觉中<br>变成了<br>再见。</body></html>
import timedef application(env,startResponse): status = 'HTTP/1.1 200 OK' responseHeaders = [('Server','bfe/1.0.8.18'),('Date','%s'%time.ctime()),('Content-Type','text/plain')] startResponse(status,responseHeaders) responseBody = str(time.ctime())return responseBody
''' 自定义的符合wsgi的框架 '''import timeclass Application(object):def __init__(self, urls):'''框架初始化的时候需要获取路由列表''' self.urls = urlsdef __call__(self, env, startResponse):''' 判断是静态资源还是动态资源。 设置状态码和响应头和响应体 :param env: :param startResponse: :return: '''# 从请求头中获取文件名 fileName = env.get('PATH_INFO')# 判断静态还是动态if fileName.startwith('/static'): fileName = fileName[7:]if '/' == fileName: filePath += '/index.html'else: filePath += fileNametry: file = None file = open(filePath, 'r', encoding='gbk') responseBody = file.read() status = 'HTTP/1.1 200 OK' responseHeaders = [('Server', 'ererbai')]except FileNotFoundError: status = 'HTTP/1.1 404 Not Found' responseHeaders = [('Server', 'ererbai')] responseBody = '<h1>找不到<h1>'finally: startResponse(status, responseHeaders)if (file != None) and (not file.closed): file.close()else: isHas = False # 表示请求的名字是否在urls中,True:存在,False:不存在for url, func in self.urls:if url == fileName: responseBody = func(env, startResponse) isHas = Truebreakif isHas == False: status = 'HTTP/1.1 404 Not Found' responseHeaders = [('Server', 'ererbai')] responseBody = '<h1>找不到<h1>' startResponse(status, responseHeaders)return responseBodydef mytime(env, startResponse): status = 'HTTP/1.1 200 OK' responseHeaders = [('Server', 'time')] startResponse(status, responseHeaders) responseBody = str(time.ctime())return responseBodydef mynews(env, startResponse): status = 'HTTP/1.1 200 OK' responseHeaders = [('Server', 'news')] startResponse(status, responseHeaders) responseBody = str('xx新闻')return responseBody'''路由列表''' urls = [ ('/mytime', mytime), ('/mynews', mynews) ] application = Application(urls)
학습 과정에서 문제가 발생하거나 학습 자료를 얻고 싶다면 학습 교류 그룹
626062078에 가입해 주세요. 함께 Python을 배워보세요!
위 내용은 Python 웹 서버 관련 지식 포인트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!