深入浅出web服务器与python应用程序之间的联系
简单来说,Web服务器是在运行在物理服务器上的一个程序,它永久地等待客户端(主要是浏览器,比如Chrome,Firefox等)发送请求。Web 服务器接受 Http Request,返回 Response,很多时候 Response 并不是静态文件,因此需要有一个应用程序根据 Request 生成相应的 Response。这里的应用程序主要用来处理相关业务逻辑,读取或者更新数据库,根据不同 Request 返回相应的 Response。两者之间的桥梁就是WSGI。
一直喜欢研究比较底层的技术, 之前就对python web框架web.py的运行机制比较迷惑, 大概学习了下之后发现flask框架以及Django框架都是基于python WSGI协议, python提供了一个简易的wsgi服务器实现--wsgiref, 在网站上找了两个例子运行了一下, 讲真, 第一次运行起来就比较懵逼, 尽管知道底层是依赖于socket, 但是深入一点就没有再研究了, 也看不懂。于是花了几天, 踏踏实实的看了源码, 一边百度一边理解, 终于学到了很多。有时候觉得自己让asp.net"惯坏"了, 因为微软闭源的关系, 自己掌握的基础知识并不全, 在很多的框架使用上, 仅仅会, 原理说个三三四四的, 还是差了很多, 果然开源就是好, 一言不合攻源码, 的确是学到了很多, python也是个很强大的语言, 这是我阅读其源码最大的感受。
对于本篇文章需要有的基础知识, 你可以从如下的链接中找到:
从零开始搭建论坛(1):Web服务器与Web框架
从零开始搭建论坛(2):Web服务器网关接口
讲真, 在没有读这两篇文章之前, 尽管我对web服务器, web框架有了解, 但还是比较模糊, 这两篇文章写的很好。伯乐在线也是个不错的技术网站!
阅读完这两篇文章后, 那就有一定的基础了。先上代码:
# main.py
1 # coding: utf-8
import time
from resty import PathDispatcher
from wsgiref.simple_server import make_server _hello_resp = '''\
<html>
<head>
<title>Hello {name}</title>
</head>
<body>
<h1>Hello {name}!</h1>
</body>
</html>''' def hello_world(environ, start_response):
# 将响应状态和响应头交给WSGI server
# from wsgiref.handlers import SimpleHandler
start_response('200 OK', [('Content-type', 'text/html')])
params = environ['params']
resp = _hello_resp.format(name=params.get('name'))
yield resp.encode('utf-8') _localtime_resp = '''\
<?xml version="1.0"?>
<time>
<year>{t.tm_year}</year>
<month>{t.tm_mon}</month>
<day>{t.tm_mday}</day>
<hour>{t.tm_hour}</hour>
<minute>{t.tm_min}</minute>
<second>{t.tm_sec}</second>
</time>''' def localtime(environ, start_response):
# 将响应状态和响应头交给WSGI server
start_response('200 OK', [('Content-type', 'application/xml')])
resp = _localtime_resp.format(t=time.localtime)
yield resp.encode('utf-8') # 模拟客户端
if __name__ == '__main__':
dispatcher = PathDispatcher()
dispatcher.register('GET', '/hello', hello_world)
dispatcher.register('GET', '/localtime', localtime) # 启动一个简易的服务器
httpd = make_server('', 8080, dispatcher)
print "Serving on port 8080..."
httpd.serve_forever() # 开启循环机制
# resty.py
1 # coding: utf-8
import cgi def notfound_404(environ, start_response):
start_response('404 Not Found', [('Content-type', 'text/plain')])
return ['Not Found'] # 使用了中间件
class PathDispatcher:
def __init__(self):
self.pathmap = {} # 使此类的对象具有函数的能力, 对象能够接受传参, 就像函数调用一样, 此函数在handlers.py 中调用
def __call__(self, environ, start_response):
path = environ['PATH_INFO']
params = cgi.FieldStorage(environ['wsgi.input'], environ=environ) method = environ['REQUEST_METHOD'].lower()
environ['params'] = {key: params.getvalue(key) for key in params} # 字典推导式
handler = self.pathmap.get((method, path), notfound_404)
return handler(environ, start_response) def register(self, method, path, function):
self.pathmap[method.lower(), path] = function
return function
然后我分析下python自带的wsgi服务器主要文件的作用:
simple_server.py模拟了一个简单的web服务器, handlers.py是wsgi协议对http协议的封装处理函数。看下图吧:
如上所示, 我大概归纳了一下不同py文件的作用。我之前对WSGI的作用比较模糊, 尽管知道WSGI就是连接web服务器与web应用程序之间的桥梁, 但是讲真!在客户端浏览器敲入换行后, python应用程序的具体执行了哪些重要的函数, 其调用顺序又是怎么来的。而且看着上面的代码,我问你一个问题:
__call__函数是啥时候调用的?在程序里面你看见了__call__的调用吗?尽管__call__函数是一个内置函数(我对其做了注释), 已经有了定义, 现在又有了实现代码, 那么调用程序呢? 原谅作为一个工科生的牛角尖, 看到程序里面有不明不白的调用实在憋屈-.-
看完下面的, 你应该就懂了

好好把<<从零开始搭建论坛(2):Web服务器网关接口>>看完, 同时要弄明白__call
__函数的作用。不过, 我先来解释下吧, 全程debug给你看看:
/////////////编程环境: win7 ////////// IDE: VS code ///////python version: 2.7.13
我分别在main.py, handlers, resty.py下了断点, 开始debug把....


当调试控制台出现 "Serving on port 8080..." 表示此时等待客户端浏览器的访问了, 下面, 我们在浏览器中写入 http://127.0.0.1:8080/hello?name=Ryan




图15注意下envron变量的值, 这就是一个dict类型的变量, 可以看到, 我们在浏览器中的 "?"后面的key-value都给保存进来了。传给了python应用程序。
当然, 要完成一个完整的url访问肯定不止这些函数模块的调用, 这就是主要的调用而已, 而且这已经很好的解释了我之前的问题了, 好了, 根据图自己去理解吧
深入浅出web服务器与python应用程序之间的联系的更多相关文章
- WEB服务器,TOMCAT和servlet之间的关系
WEB服务器,TOMCAT和servlet之间的关系 什么是WEB服务器Web服务器是指能够为发出请求的浏览器提供文档的程序.服务器是 一种被动程序,只有浏览器发出请求的时候才会响应.应用层使用 的是 ...
- python多进程程序之间交换数据的两种办法--Queue和Pipe
合在一起作的测试. #!/usr/bin/env python # -*- coding: utf-8 -*- import multiprocessing import random import ...
- 一文读懂Python web框架和web服务器之间的关系
我们都知道 Python 作为一门强大的语言,能够适应快速原型和较大项目的制作,因此被广泛用于 web 应用程序的开发中. 在面试的过程中,大家或多或少都被问到过这样一个问题:一个请求从浏览器发出到数 ...
- python之Web服务器案例
HTTP协议简介 1. 使用谷歌/火狐浏览器分析 在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来.而浏览器和服务器之间的传输协议是HTTP,所以: ...
- WEB服务器、应用程序服务器、HTTP服务器区别
很清晰的解释了WEB服务器.应用程序服务器.HTTP服务器区别 转载自 http://www.cnblogs.com/zhaoyl/archive/2012/10/10/2718575.html WE ...
- WEB服务器、应用程序服务器、HTTP服务器区别(转)
WEB服务器.应用程序服务器.HTTP服务器有何区别?IIS.Apache.Tomcat.Weblogic.WebSphere都各属于哪种服务器,这些问题困惑了很久,今天终于梳理清楚了: Web服务器 ...
- WEB服务器、应用程序服务器区别
WEB服务器.应用程序服务器.HTTP服务器有何区别?IIS.Apache.Tomcat.Weblogic.WebSphere都各属于哪种服务器,这些问题困惑了很久,今天终于梳理清楚了: Web服务器 ...
- (转)Python的web服务器
1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”). WSGI允许开发者将选择web框架和web ...
- WEB服务器、应用程序服务器、HTTP服务器的区别
WEB服务器.应用程序服务器.HTTP服务器的区别 Web服务器: 基本功能就是提供Web信息浏览服务.它只需支持HTTP协议.HTML文档格式及URL.与客户端的网络浏览器配合.因为Web服务器主要 ...
随机推荐
- FFmpeg源代码简单分析:libswscale的sws_scale()
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- Cocos2D实现RPG队伍菜单任意调整角色顺序的效果
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 前一篇我们实现了队伍实现拖尾效果,但是在实际游戏中我们往往需要 ...
- Centos7安装JStorm2.1.1
系统环境 Centos7 外网ip 182.254.145.66 内网ip 10.105.23.114 安装位置 /usr/local/jstorm-2.1.1 安装zookeeper 参见 htt ...
- C++对象模型的那些事儿之四:拷贝构造函数
前言 对于一个没有实例化的空类,编译器不会给它默认生成任何函数,当实例化一个空类后,编译器会根据需要生成相应的函数.这类函数包括一下几个: 构造函数 拷贝构造函数 析构函数 赋值运算符 在上一篇博文C ...
- C++三目运算符的增强
<p>// 在C语言中表达式的结果放在寄存器中 // 在C语言中,表达式的返回值是变量的值 // 在C++中,表达式返回的是变量的本身</p><pre name=&quo ...
- iOS中 动态启动图GIF的简单设置 韩俊强的博客
// 设定位置和大小 CGRect frame = CGRectMake(50,340,[UIScreen mainScreen].bounds.size.width / 2,[UIScreen ma ...
- Linux Debugging(三): C++函数调用的参数传递方法总结(通过gdb+反汇编)
上一篇文章<Linux Debugging:使用反汇编理解C++程序函数调用栈>没想到能得到那么多人的喜爱,因为那篇文章是以32位的C++普通函数(非类成员函数)为例子写的,因此只是一个特 ...
- Leetcode_7_Reverse Integer
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41578077 Reverse Integer Revers ...
- GIT版本控制 — GIT与SVN的相互转换 (三)
git-svn git-svn用于Git和SVN的转换,可以把Git仓库迁移成SVN仓库,反之亦可. 详细介绍可见[1],或者命令行输入git-svn. Bidirectional operation ...
- Android数据库Realm实践
Android开发中常用的数据库有5个: 1. OrmLite OrmLite 不是 Android 平台专用的ORM框架,它是Java ORM.支持JDBC连接,Spring以及Android平台. ...