服务器的作用是什么,服务器的用途与主要功能介绍

在上文中,我给大家留了一个问题:如何在不对服务器代码作任何修改的情况下,通过该服务器运行Djando应用、Flask应用和Pyramid应用,同时满足这些不同网络框架的要求?读完这篇文章,你就可以回答这个问题了。 以前,你选择的Python网络框架将会限制所能够使用的网络服务器,反之亦然。如果框架和服务器在设计时就是可以相互匹配的,那你就不会面临这个问题: 但是如果你试图将设计不相匹配的服务器与框…

在上原文中,我给大伙儿留了一个问题:怎样在错误服务器编码作一切改动的前提下,根据该服务器运作Djando运用、Flask运用和Pyramid应用,一起达到这种不一样网络框架的需要?看完本文,你就可以回应这个问题了。

之前,你挑选的Python网络框架可能限定所可以采用的网络服务器,相反也是。假如框架和服务器在设计方案时便是能够互相搭配的,那你就不会遭遇这个问题:

从零开始开发一个 Web 服务器(2)

可是假如你尝试将设计方案不相对应的服务器与框架相融合,那么你毫无疑问便会遇到下边这张图所呈现的这个问题:

从零开始开发一个 Web 服务器(2)

这就代表着,你大部分只有应用可以正常运转的服务器与框架组成,而不可以选择你期待应用的服务器或框架。

那样,你如何保证能够在没有改动网络服务器编码或网络框架代码的情况下,应用自己选择的服务器,而且配对好几个不一样的网络框架呢?因为处理这个问题,就出现了Python Web服务器网关ip插口(Python Web Server Gateway Interface,通称“WSGI”)。

从零开始开发一个 Web 服务器(2)

WSGI的发生,让开发者能将网络框架与网络服务器的挑选隔开起来,不会再互相限定。如今,你能真真正正地将不一样的网络服务器与网络开发设计框架开展混和配搭,挑选满足自己要求的组成。比如,你可以用Gunicorn或Nginx/uWSGI或Waitress服务器来运作Django、Flask或Pyramid运用。恰好是因为服务器和框架均适用WSGI,才真真正正得以实现二者之间的随意混和配搭。

因此,WSGI便是我还在上一篇文章中常留问题的答案。你网络服务器务必完成一个服务器端WSGI插口,而现阶段全部当代Python网络框架都已实现了框架端WSGI插口,那样开发者不用改动服务器的编码,就能够适用某一网络框架。

网络服务器和网络框架适用WSGI协议书,不但让运用开发者挑选满足自身要求的组成,从而有益于服务器和框架的开发者,因为他们能将注意力集中在自已擅长的领域,而非互相掣肘。别的计算机语言也有着相近的插口:比如Java的Servlet API和Ruby的Rack。

空口无凭,我想你毫无疑问在想:“无代码无实情!”既然这样,我一直在这里得出一个非常简单的WSGI服务器完成:

# Tested with Python 2.7.9, Linux & Mac OS Ximport socketimport StringIOimport sysclass WSGIServer(object):address_family = socket.AF_INETsocket_type = socket.SOCK_STREAMrequest_queue_size = 1def __init__(self, server_address):# Create a listening socketself.listen_socket = listen_socket = socket.socket(self.address_family,self.socket_type)# Allow to reuse the same addresslisten_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# Bindlisten_socket.bind(server_address)# Activatelisten_socket.listen(self.request_queue_size)# Get server host name and porthost, port = self.listen_socket.getsockname[:2]self.server_name = socket.getfqdn(host)self.server_port = port# Return headers set by Web framework/Web applicationself.headers_set = def set_app(self, application):self.application = applicationdef serve_forever(self):listen_socket = self.listen_socketwhile True:# New client connectionself.client_connection, client_address = listen_socket.accept# Handle one request and close the client connection. Then# loop over to wait for another client connectionself.handle_one_requestdef 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 dataenv = self.get_environ# It\'s time to call our application callable and get# back a result that will become HTTP response bodyresult = self.application(env, self.start_response)# Construct a response and send it back to the clientself.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, # GETself.path, # /helloself.request_version # HTTP/1.1) = request_line.splitdef 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 variablesenv[\'wsgi.version\'] = (1,0)env[\'wsgi.url_scheme\'] = \'http\'env[\'wsgi.input\'] = StringIO.StringIO(self.request_data)env[\'wsgi.errors\'] = sys.stderrenv[\'wsgi.multithread\'] = Falseenv[\'wsgi.multiprocess\'] = Falseenv[\'wsgi.run_once\'] = False# Required CGI variablesenv[\'REQUEST_METHOD\'] = self.request_method # GETenv[\'PATH_INFO\'] = self.path # /helloenv[\'SERVER_NAME\'] = self.server_name # localhostenv[\'SERVER_PORT\'] = str(self.server_port) # 8888return envdef start_response(self, status, response_headers, exc_info=None):# Add necessary server headersserver_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_responsedef finish_response(self, result):try:status, response_headers = self.headers_setresponse = \'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.closeSERVER_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

以上的编码比第一部分的网络服务器完成编码要长的多,可是这种编码具体也不会过长,仅有不上150行,大伙儿了解下去并不会太艰难。上边这一服务器的作用也越多——它能够运作你应用自己喜欢的架构所作出去的网络技术应用,无论你挑选Pyramid、Flask、Django或者其它适用WSGI协议书的架构。

你不相信?你可以自己测试一下,看一下结果如何。将以上编码储存为 webserver2.py,或是立即从我的Github仓库免费下载。假如你运作该文档时没给予一切主要参数,那样程序流程便会出错并撤出。

$ python webserver2.pyProvidea WSGI application object as module:callable

以上程序流程设计的目的,便是运作你研发的网络技术应用,但是你还要达到一些它规定。要运作网络服务器,你只必须组装Python就可以。可是要运作应用Pyramid、Flask和Django等架构研发的网络技术应用,你还要先组装这种架构。大家下面组装这三种架构。我侧重于应用 virtualenv组装。请依照下边的提醒建立并激话一个虚拟器,随后组装这三个互联网架构。

$ [sudo] pip install virtualenv$ mkdir ~/envs$ virtualenv ~/envs/lsbaws/$ cd ~/envs/lsbaws/$ lsbin include lib$ source bin/activate(lsbaws) $ pip install pyramid(lsbaws) $ pip install flask(lsbaws) $ pip install django

下面,你必须建立一个网络技术应用。大家最先建立Pyramid运用。将下边的编码储存为 pyramidapp.py文档,放至webserver2.py所属的文件中,或是立即从我的Github仓库免费下载该文档:

from pyramid.config import Configuratorfrom pyramid.response import Responsedef hello_world(request):return Response(\'Hello world from Pyramid!n\',content_type=\'text/plain\',)config = Configuratorconfig.add_route(\'hello\', \'/hello\')config.add_view(hello_world, route_name=\'hello\')app = config.make_wsgi_app

如今,你能通过自身研发的网站服务器来运行里面的Pyramid运用。

(lsbaws) $ python webserver2.py pyramidapp:appWSGIServer:ServingHTTP on port8888...

在运作 webserver2.py时,你告知自己的服务器去载入pyramidapp控制模块里的app可启用目标(callable)。你网络服务器现在可以接受HTTP要求,并把要求转站至你Pyramid运用。运用现阶段只有解决一个路由器(route):/hello。在浏览器的搜索框键入http://localhost:8888/hello,按住回车,观查会有什么原因:

从零开始开发一个 Web 服务器(2)

你还能够在命令行应用 curl指令,来检测服务器运行情况:

$ curl -v http://localhost:8888/hello...

下面大家建立Flask运用。多次重复上边的流程。

from flask import Flaskfrom flask import Responseflask_app = Flask(\'flaskapp\')@flask_app.route(\'/hello\')def hello_world:return Response(\'Hello world from Flask!n\',mimetype=\'text/plain\')app = flask_app.wsgi_app

将里面的编码储存为 flaskapp.py,或是立即从我的Github仓库免费下载文档,并运作:

(lsbaws) $ python webserver2.py flaskapp:appWSGIServer:ServingHTTP on port8888...

随后在浏览器搜索框键入 http://localhost:8888/hello,并按住回车键:

从零开始开发一个 Web 服务器(2)

一样,在命令行应用 curl指令,看一下服务器是否会回到Flask运用产生的消息:

$ curl -v http://localhost:8888/hello...

这一服务器是否也可以适用Django运用?试一试就知道了!但是接下来的实际操作更加繁杂一些,我提议大伙儿复制全部库房,并运用当中的 djangoapp.py文档。下边的编码将一个名字叫做helloworld的Django运用加上至现阶段的Python途径中,随后导进了此项目地WSGI运用。

import syssys.path.insert(0, \'./helloworld\')from helloworld import wsgiapp = wsgi.application

将里面的编码储存为 djangoapp.py,并运用你开发的服务器运作这一Django运用。

(lsbaws) $ python webserver2.py djangoapp:appWSGIServer:ServingHTTP on port8888...

一样,在浏览器中键入 http://localhost:8888/hello,并按住回车:

从零开始开发一个 Web 服务器(2)

下面,和之前几回一样,你根据命令行应用 curl指令开展检测,确认了这一Djando运用取得成功处理了你发送的申请:

$ curl -v http://localhost:8888/hello...

你有没有依照上边的过程检测?你做到了让服务器适用所有三种架构吗?要是没有,请尽可能亲自动手实际操作。阅读文章编码至关重要,但这系列产品文章内容的目的是为了再次开发,而这代表你必须自身亲力亲为。最好是是你自己重新输入每一个编码,并保证程序执行结论符合预期。

经由上边的详细介绍,你应当早已了解到WSGI的强劲之处:它可以让你随意混和配搭互联网服务器和架构。WSGI为Python网络服务器与Python网络架构中间的互动带来了一个简约的插口,并且很容易在服务器端和架构端完成。下边的字符串常量各自展示了服务器端和架构端WSGI插口:

def run_application(application):\"\"\"Server code.\"\"\"# This is where an application/framework stores# an HTTP status and HTTP response headers for the server# to transmit to the clientheaders_set = # Environment dictionary with WSGI/CGI variablesenviron = {}def start_response(status, response_headers, exc_info=None):headers_set[:] = [status, response_headers]# Server invokes the ‘application\' callable and gets back the# response bodyresult = application(environ, start_response)# Server builds an HTTP response and transmits it to the clientdef app(environ, start_response):\"\"\"A barebones WSGI app.\"\"\"start_response(\'200 OK\', [(\'Content-Type\', \'text/plain\')])return [\'Hello world!\']run_application(app)

下边给各位解释一下以上编码的原理:

  1. 互联网架构给予一个命名为 application的可启用目标(WSGI协议书并没特定如何做到这一目标)。
  2. 服务器每一次从HTTP手机客户端接受要求以后,启用 application。它会向可启用目标传送一个名字叫做environ的词典做为主要参数,在其中包括了WSGI/CGI的许多变量值,和一个名叫start_response的可启用目标。
  3. 架构/运用形成HTTP状态码及其HTTP回应报头(HTTP response headers),随后将二者传送至 start_response,等候服务器储存。除此之外,架构/运用还将回到回应的文章正文。
  4. 服务器将状态码、回应报头和回应文章正文组成HTTP回应,并返还给手机客户端(这一步并不属于WSGI协议书)。

下边这张图形象化地说明了WSGI插口的状况:

从零开始开发一个 Web 服务器(2)

有一点要提醒大家,如果你应用以上架构开发网络技术应用的情况下,你解决是指更高层住宅级的逻辑性,并不会立即解决WSGI协议书有关的规定,但是我比较清楚,既然你正在看本文,你一定对架构端WSGI插口特别感兴趣。因此,人们下面在不使用Pyramid、Flask或Djando架构的情况下,自身开发一个简约的WSGI网络技术应用/互联网架构,并应用WSGI服务器运作该运用:

def app(environ, start_response):\"\"\"A barebones WSGI application.This is a starting point for your own Web framework :)\"\"\"status = \'200 OK\'response_headers = [(\'Content-Type\', \'text/plain\')]start_response(status, response_headers)return [\'Hello world from a simple WSGI application!n\']

将以上代码保存为 wsgiapp.py文档,或是立即从我的Github仓库免费下载,随后运用网站服务器运作该运用:

(lsbaws) $ python webserver2.py wsgiapp:appWSGIServer:ServingHTTP on port8888...

在浏览器中键入下面的图里的详细地址,之后按回车。结论应该是这样的:

从零开始开发一个 Web 服务器(2)

你刚自身撰写了一个简约的WSGI互联网架构!太难以置信了。

下面,大家再次剖析缺少对象给手机客户端的目标。下边这张图展现的你根据HTTP手机客户端启用Pyramid运用后,网络服务器形成的HTTP回应:

从零开始开发一个 Web 服务器(2)

图中里的回应与你在第一篇中见到的一些相近,可是也是有显著不同点。举例说明,在其中就出现了你以前没有看到过的4歌HTTP报头:Content-Type,Content-Length,Date和Server。这些事互联网缺少对象的回应目标一般都是会包括的报头。但是,这四个都不是必须的。报头的目的是传送相关HTTP要求/回应的附加消息。

既然你早已对WSGI插口拥有更加深入的了解,下边这张图对回应目标的具体内容进行了更详尽的说明,说明了每一条内容是怎样形成的。

从零开始开发一个 Web 服务器(2)

到现在为止,我还没有详细介绍过 environ词典的主要内容,但简单来说,这是一个务必包含着WSGI协议书所选定的一些WSGI和CGI自变量。网络服务器从HTTP要求中获得词典需要的值。下边这张图展现是指词典的详细内容:

从零开始开发一个 Web 服务器(2)

互联网架构根据该词典给予的信息内容,依据规定的路由器和要求方式等基本参数来确定应用哪一个主视图(views),从哪儿载入要求文章正文,及其怎样导出错误报告。

目前为止,你早已取得成功建立了自身的适用WSGI协议书的网站服务器,还使用不一样的互联网架构开发设计了好几个网络技术应用。此外,你还是自身研发了一个简约的互联网架构。本篇文章详细介绍的具体内容不可以说不丰富多彩。大家下面回顾一下WSGI网站服务器如何处理HTTP要求:

  • 最先,服务器启动并载入互联网架构/运用给予的 application可启用目标
  • 随后,网络服务器载入一个要求信息内容
  • 随后,网络服务器对申请开展分析
  • 随后,网络服务器应用请求数据建立一个名字叫做 environ的词典
  • 随后,网络服务器以 environ词典和start_response可启用目标做为主要参数,启用application,并得到运用产生的回应文章正文。
  • 随后,网络服务器依据启用 application目标后返回的数据信息,及其start_response设定的状态码和回应标题文字,搭建一个HTTP回应。
  • 最终,网络服务器将HTTP回应回到至手机客户端
从零开始开发一个 Web 服务器(2)

之上便是第二部分的全部内容。你现在已经有着了一个正常运转的WSGI网络服务器,能够适用根据遵循WSGI协议书的互联网架构所作的网络技术应用。最棒的是,这种网络服务器能够不用作一切代码改动,就能够与好几个互联网架构相互配合应用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年7月15日 上午11:45
下一篇 2022年7月15日 上午11:50

相关推荐

  • 徐福记月饼怎么样好不好吃(评测徐福记月饼)

    一年一度的月饼节又来了!五仁豆沙莲蓉蛋黄肉松等不同口味的月饼琳琅满目,甚至还有很多新奇口味的搭配,商家用尽各种办法,推出各种创意设计吸引消费者,对消费者来说,送礼的选择越来越多,但是怎样选择既体面有内涵有新意,并且还健康好吃的月饼礼盒呢?近期被徐福记四款既养生又高颜值的礼盒刷屏,分别是徐福记·呈味空间黑松露流心酥礼盒,还有今年与颐和园IP合作走“国潮”风的定制款:禧礼礼盒、锦凤挚礼礼盒、颐福献礼礼…

    2022年8月28日
    630
  • 电商代运营收费标准,电商代运营一般几个点提成

    近些年,随着电商的发展,代运营也慢慢火起来,但是作为淘宝卖家,你知道代运营的收费模式吗? 其实,作为外包代运营公司,为了帮助商家提高销量,增加复购率,收费模式慢慢变得多元化了。 开店初期困扰 淘宝代运营的几种收费模式? 1,收取基本的服务费。比如开通店铺,整店装修的费用。这个费用一般是一次性的,收取的方式是以项目交接而结束的。 2,收取佣金的模式。一般外运营公司针对优质的产品会和商家协议分红,帮助…

    2022年8月8日
    1820
  • 怎样做淘宝直播,个人做淘宝直播步骤

    其实直播是一场秀,一场有内容有程序的秀,什么样的东西吸引人或者怎么符合你的店铺,这些都需要有策划,不能说太随意的乱播。 首先,虽然官方说开通不需要花钱,但是不是符合条件以及有等级的开直播,对于小店来说很难。所以就要找那些专门做这一行的,给钱帮忙开通。 开通了直播权限你以为就百事大吉了,这只是刚刚开始。 因为淘宝直播中还有一个叫浮现权的东西,简单的说,没有这个浮现权淘宝自然分流会很少,或者几乎没有,…

    2022年7月5日
    650
  • 房地产营销策略,做房地产销售有哪些营销套路

    大家在买房子时,去售楼处看房子,总是有很多人在那挑选,甚至为了一套房子你争我抢。这时你就要擦亮眼睛,看看是不是开发商的套路,开发商会想尽办法让自己的房子热卖,有时会做一些假象。那么,房地产销售有哪些营销套路呢?下面小编就为大家具体的讲一讲,一起来仔细看看吧! 造势套路 人们都有爱凑热闹的习惯,觉得看的人多、买的人多,一定就不会差。人气是开发商销售楼盘重要考虑因素,如果售楼处连个人影都没有,谈何卖房…

    2022年5月20日
    710
  • 上班族如何赚外快,挣钱发财的多种方法大揭秘

    我时常听见身边的人跟我抱怨吐槽说,现在这个社会赚钱真难,什么都在快速增长,唯独工资像蜗牛一样慢慢上涨。赚钱真是太难了! 现代社会里,赚钱这件事说难也不难,但说容易也不容易,关键是看你以怎样的心态去对待。 比如我自己,对于赚钱这件事之前的我特别焦虑,因为我是一名自由撰稿人,没有上班,平常做自媒体以及靠写文章赚钱,但这件事又是“靠天吃饭”,因为我没有赶上前两年的自媒体红利,只能勉勉强强的跟着屁股后面跑…

    2022年6月10日
    730
  • 网络创业项目有哪些,个人互联网创业项目推荐

    很多人都是通过网络达到了自己的赚钱目的,那么最新网赚好项目都是有哪些,网赚项目有哪些我们可以去做,那么接下来就给你们带来最新网赚项目,让我们都可以轻松的获得收入。 1、淘宝客 最新网赚项目,相信大家对于这方面的东西都是非常的熟悉了,这是淘宝下面的一款产品,他的赚钱方式也是非常的简单,我们在上面可以将我们自己感兴趣的东西推广出来,然后别人点击之后购买了我们的产品,那么就可以进行赚钱的,我们去做这个东…

    2022年6月5日
    690
  • 自媒体文章怎么写,自媒体文章写作步骤与方法

    总有很多人跟我反馈说,秦老师我不知道怎么去写文章,不知道如何写出让读者愿意看的文章,我根本就不具备互联网思维,也没有新媒体思维,不知道如何写出爆文,我说其实刚开始我也是不会的,但是我一点点的学习,一点点的成长。 然后才有了一点点的知识,他说那到底应该如何去做,我说我们需要去掌握它的内在核心本质,就像刚才我们说的如何去拥有互联网思维,如何去用新媒体思维,首先我们要去学习,怎么学习?就是要摸清楚新媒体…

    2022年6月21日
    580
  • 在淘宝购物如何省钱,淘宝买东西省钱的方法

    今天在网上发现一个淘宝购物可以帮我们省钱的方法。本人已经验证了是真的能帮我们省一些钱。方法就是比如你要在淘宝上买一个你喜欢的东西你可以复制它的名称,下一个粉象生活app,打开这个app,在里面能领到一些买该商品的优惠卷。 具体操作如:第一步:你在淘宝任意找一款产品,比如我随便搜索一个拉杆箱,这款拉杆箱最便宜的一款是208元 第二步:复制淘宝这款拉杆箱的标题,然后打开粉象生活APP,会弹出一个“粘贴…

    2022年6月5日
    630
  • 小米理财怎么样,小米金融的理财产品推荐

    目前智能手机系统中,众多品牌已经开始涉及钱包应用,其中小米和华为就是最为典型的例子,今天上午,据业内消息称,小米钱包刚推出了一款名为货币基金的理财服务。 从介绍上看,小米似乎已经与基金公司合作,其名为易方达天天理财货币基金A,代号为000009,从说明上看,其7日年化收益竟然达到了6.437%,而万份收益超过3元。 相比此前支付宝推出的余额宝相比,小米理财似乎是在向阿里巴巴和腾讯微信发起挑战,而小…

    2022年6月20日
    690
  • 推广平台有那些,5大免费的网络推广平台

    主流自媒体推广平台有哪些?如何用自媒体引流?随着互联网的高速发展,各种网络营销手段层出不穷。为了能够快速的占领市场,企业开始关注自媒体这个引流平台。很多网络营销新人对于当前国内主流的自媒体推广平台了解甚少,下面就给大家简单介绍几个。 头条号 最开始做自媒体的话,强烈推荐做今日头条。一般意义上来说,当用户在头条号进行文章或者视频发布时,头条首先会进行查重过滤旧闻。能通过查重,头条给的一级推荐量都是差…

    2022年5月27日
    700

发表回复

登录后才能评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信