eventlet 的 wsgi 模块提供了一种启动事件驱动的WSGI服务器的简洁手段,可以将其作为某个应用的嵌入web服务器,或作为成熟的web服务器,一个这样的web服务器的例子就是 Spawning

  目录

  一、Eventlet 的 WSGI 服务器

    1. eventlet.wsgi.server()

    2. eventlet.wsgi.format_data_time()

  二、SSL

  三、Post hooks

  四、“100 continue”响应头

一、Eventlet 的 WSGI server

  要启动一个 wsgi 服务器,只需要创建一个套接字,然后用它调用 eventlet.wsgi.server() 就可以。

  例如:

from eventlet import wsgi
import eventlet def hello_world(env, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello, World!\r\n'] wsgi.server(eventlet.listen(('', 8090)), hello_world)

  这个简单的 server 使用 eventlet.listen() 创建了一个套接字,wsgi.server() 监听对应的地址、端口等,将请求传递给 WSGI 应用 hello_world 处理。

  一个稍微形象一些的例子如下:

import eventlet
from eventlet import wsgi def hello_world(env, start_response):
if env['PATH_INFO'] != '/':
start_response('404 Not Found', [('Content-Type', 'text/plain')])
return ['Not Found\r\n']
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello, World!\r\n'] wsgi.server(eventlet.listen(('', 8090)), hello_world)

  这个例子非常简洁地诠释了 WSGI 的应用接口规范,也涵盖了 eventlet.wsgi 模块中起 server 的用法。

1.

eventlet.wsgi.server()

eventlet.wsgi.server(
socket,
site,
log=None,
environ=None,
max_size=None,
max_http_version='HTTP/1.1',
protocol=<class eventlet.wsgi.HttpProtocol at 0x7f4f68192f58>, server_event=None,
minimum_chunk_size=None,
log_x_forwarded_for=True,
custom_pool=None,
keepalive=True,
log_output=True,
log_format='%(client_ip)s - - [%(date_time)s] "%(request_line)s" %(status_code)s %(body_length)s %(wall_seconds).6f',
url_length_limit=8192,
debug=True,
socket_timeout=None,
capitalize_response_headers=True)

  这个调用封装了很多功能,创建一个 WSGI server 来处理指定套接字中产生的请求,这个函数会一直循环下去,即时刻监听请求。当 server 退出时,对应的套接字对象 socket 也会被关闭但是底层的文件描述字会被保留,所以这个时候如果用这个 socket 调用 dup() ,将会仍然可以使用。

  参数:

socket Server socket, 已经绑定一个端口且监听中
site 实现 WSGI 应用的函数

log

日志输出的位置,应该是一个类文件(file-like)对象,缺省为 sys.stderr
environ 添加到每一次请求的 environ 字典中的额外参量
max_size 这个 server 时刻允许的最大客户端连接数
max_http_version 设为 “HTTP/1.0” 会只支持 HTTP 1.0. 可以支持那些在 HTTP 1.1 下并不能正常工作的应用
protocol 弃用,协议类
server_event 弃用,用来收集 Server 对象
minimum_chunk_size 以字节记的HTTP块的最小尺寸。 可以用来改进哪些产生很多小字串的应用的性能。尽管使用它在技术上违背 WSGI 规范,但可以通过设置environ[‘eventlet.minimum_write_chunk_size’]来在每次请求的程度上覆写
log_x_forwarded_for 如果为 True (缺省), 除了在日志的 ‘client_ip’ 段记录实际的客户端 ip 地址外,还记录HTTP头中的 x-forwarded-for 的内容
custom_pool 一个定制的 GreenPool 实例,用来孵化客户端的 greenthreads. 如果设置了该项,无视参数 max_size
keepalive 设为False 会禁止 server keepalives,所有的连接都会在服务完一个请求后关闭
log_output Boolean 值,指示 server 是否记录日志
log_format A python format string that is used as the template to generate log lines. The following values can be formatted into it: client_ip, date_time, request_line, status_code, body_length, wall_seconds. The default is a good example of how to use it
url_length_limit 请求URL的最大长度,如果超长,返回414错误
debug 如果想要服务器将异常追溯信息子啊500错误中发回给客户端,这里就设置为True。 如果这里设置为 False,server 将会响应空值
socket_timeout 客户端连接的套接字操作超时限制,缺省为 None,意味着永久等待
capitalize_response_headers 大写响应头的字段名称,缺省为True

2.

eventlet.wsgi.format_date_time(timestamp)

  将Unix时间戳格式化为一个 HTTP 标准字符串。

二、SSL

  要创建一个安全的 server ,只需要传入一个 SSL 包裹的套接字即可:

wsgi.server(eventlet.wrap_ssl(
eventlet.listen(('', 8090)),
certfile='cert.crt',
keyfile='private.key',
server_side=True),
hello_world)

  应用可以通过环境变量  env['wsgi.url_scheme']  判断自己是不是在一个SSL server中。

三、支持 Post Hooks的非标准扩展

  Eventlet 的 WSGI server 支持对于 WSGI 规范的非标准扩展——用 env['eventlet.posthooks'] 包含一个有若干post hooks 的数组,这些 post hooks 会在完全发送完响应后被调用。每一个 post hook 是一个格式为 (func, args, kwargs) 的元组,以 WSGI environment 字典加  args 和 kwargs 为参数调用 func。

  例如:

from eventlet import wsgi
import eventlet def hook(env, arg1, arg2, kwarg3=None, kwarg4=None):
print('Hook called: %s %s %s %s %s' % (env, arg1, arg2, kwarg3, kwarg4)) def hello_world(env, start_response):
env['eventlet.posthooks'].append(
(hook, ('arg1', 'arg2'), {'kwarg3': 3, 'kwarg4': 4}))
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello, World!\r\n'] wsgi.server(eventlet.listen(('', 8090)), hello_world)

  上面的代码会为每一个处理的请求打印 WSGI 环境和其他的函数参数。

  当需要在完全响应一个客户端请求后(或客户端过早地断开连接后)执行一段代码时 Post hook 非常有用。 一个例子就是精确记录带宽的使用情况,因为用户断开连接时消耗的带宽小于 Content-Length 中标出的值。

四、“100 Continue” 响应头

  Eventlet 的 WSGI server 支持发送(可选的)headers 和 HTTP “100 Continue” 临时响应. This is useful in such cases where a WSGI server expects to complete a PUT request as a single HTTP request/response pair, and also wants to communicate back to client as part of the same HTTP transaction. An example is where the HTTP server wants to pass hints back to the client about characteristics of data payload it can accept. As an example, an HTTP server may pass a hint in a header the accompanying “100 Continue” response to the client indicating it can or cannot accept encrypted data payloads, and thus client can make the encrypted vs unencrypted decision before starting to send the data).

  This works well for WSGI servers as the WSGI specification mandates HTTP expect/continue mechanism (PEP333).

  要定义 “100 Continue” 响应头, 需要调用 env['wsgi.input'] 里的 set_hundred_continue_response_header() 如下:

from eventlet import wsgi
import eventlet def wsgi_app(env, start_response):
# Define "100 Continue" response headers
env['wsgi.input'].set_hundred_continue_response_headers(
[('Hundred-Continue-Header-1', 'H1'),
('Hundred-Continue-Header-k', 'Hk')])
# The following read() causes "100 Continue" response to
# the client. Headers 'Hundred-Continue-Header-1' and
# 'Hundred-Continue-Header-K' are sent with the response
# following the "HTTP/1.1 100 Continue\r\n" status line
text = env['wsgi.input'].read()
start_response('200 OK', [('Content-Length', str(len(text)))])
return [text]

Python——eventlet.wsgi的更多相关文章

  1. WSGI学习系列eventlet.wsgi

    WSGI是Web Service Gateway Interface的缩写. WSGI标准在PEP(Python Enhancement Proposal)中定义并被许多框架实现,其中包括现广泛使用的 ...

  2. Python的WSGI(Web Server Gateway Interface)服务器

    Python的WSGI(Web Server Gateway Interface)服务器 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任.

  3. Python——eventlet

    eventlet语境下的“绿色线程”普通线程之间的区别: 1. 绿色线程几乎没有开销,不用像保留普通线程一样保留“绿色线程”,每一个网络连接对应至少一个“绿色线程”: 2. 绿色线程需要人为的设置使其 ...

  4. Python记录wsgi

    类实现wsgi app from wsgiref.util import setup_testing_defaults from wsgiref.simple_server import make_s ...

  5. ubuntu python apache2 wsgi django框架

    在ubuntu上通过apatch2和wsgi部署django (亲手做过!!!) 一,我的python.django.apatch2版本: python:python -V 2.7.3 django: ...

  6. python之WSGI与Guincorn

    WSGI与Guincorn WSGI WSGI (Web Server Gateway Interface),WSGI是为Python语言定义的Web服务器和Web应用程序之间的一种通用接口. 如下图 ...

  7. python的WSGI接口

    WSGI:Web Server Gateway Interface. WSGI是为python语言定义的web服务器和web应用程序或框架之间的一种简单而实用的接口.wsgi是一个web组件的接口规范 ...

  8. Python——eventlet.websocket

    使用该模块可以方便地创建 websocket 服务器,要创建一个websocket服务器,只需要将一个句柄函数用装饰器 WebSocketWSGI 装饰即可,然后这个函数就可以当做一个WSGI应用: ...

  9. Python——eventlet.hubs

    Hub构成了 Eventlet 的事件循环,它分发 I/O 事件.调度 greenthread.Hub的存在使得协程被提升为 greenthreads. Eventlet 有多种hub的实现,所以在使 ...

随机推荐

  1. linux命令(43):awk的使用技巧

    AWK是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Fam ...

  2. [整理]Unity3D游戏开发之Lua

    原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...

  3. 【Java】异常类处理层次

    异常处理简介 异常在java的开发中可能没有那么被重视.一般遇到异常,直接上抛,或者随便catch一下处理之后对于程序整体运行也没有什么大的影响.不过在企业级设计开发中,异常的设计与处理的好坏,往往就 ...

  4. C#学习笔记(11)——深入事件,热水器案例

    说明(2017-6-14 15:04:13): 1. 热水器案例,为了便于理解,采用了蹩脚但直观的英文命名,哼哼. heater类,加热,声明一个委托,定义一个委托事件: using System; ...

  5. 3. DNN神经网络的正则化

    1. DNN神经网络的前向传播(FeedForward) 2. DNN神经网络的反向更新(BP) 3. DNN神经网络的正则化 1. 前言 和普通的机器学习算法一样,DNN也会遇到过拟合的问题,需要考 ...

  6. Android 开发自己的网络收音机1——功能要求及设计方案

    最近打算利用业余时间,编写一个Android的网络收音机.因为我自己偶尔也喜欢听听广播,所以打算用业余时间编写一个网络版收音机.说起收音机,其实在工作中已经编写过一个,不过那个收音机是需要硬件支持,也 ...

  7. Quartz Scheduler Calendar日历的使用

    Quartz Calendar 日历的使用 quartz引擎为我们提供了日历的功能,让我们可以自己定义一个时间段,可以控制触发器在这个时间段内触发或者不触发,比如可以设置节假日,工作时间早8晚5等等. ...

  8. Java 源码赏析 - java.lang - Void

    被人鄙视了,于是也来读读源码... package java.lang; /** * The Void class is an uninstantiable placeholder class to ...

  9. Hibernate执行原生SQL

    1.查询指定字段 public List<Object[]> getUseList( Integer index, Integer offset, String state, String ...

  10. Jna & twain

    参考海康威视Java版示例(采用Jna实现) 获得win32原生窗口句柄:HWND hwnd = new HWND(Native.getComponentPointer(panelRealplay)) ...