Odooweb机制浅析
Odoo作为开源ERP,在欧洲有着广泛的应用,但就中国来说,基本上还处于起步阶段,国内的应用并不是太多,因此,从市场来看,其应用潜力是巨大的。要基于Odoo进行二次开发,就必须要对Odoo的web基本运行原理有必要的了解,才能从宏观上对Odoo有个大体认识。此文正是基于此目的,进行简要的分析,希望能够对开发Odoo应用有帮助。
Odoo使用的编程语言为python,python本身并不能直接处理web请求,就好比java并不能直接处理web请求一样,都需要一个媒介或桥梁,那么 要使基于python的Odoo能够处理来自WebServer包装之后的请求,这个媒介或桥梁是什么呢? 这个桥梁就是WSGI. 那么到底什么是WSGI呢?
1 WSGI
WSGI的官方定义:the Python WebServer Gateway Interface。顾名思义,这就是一个Gateway,也就是网关,具体标准请参看 http://legacy.python.org/dev/peps/pep-0333/
(注:以下内容摘自文章【1】)
网关的作用就是在协议之间进行转换,如下图所示
WSGI一边连着web服务器,另一边连着用户的应用。但是,这个桥的功能很弱,有时候还需要别的桥来帮忙才能进行处理,如下图所示:
在上图中:
wsgiapp又称应用 ,就是一个WSGIapplication。
wsgi container ,又称容器 ,虽然这个部分常常被称为handler,handler容易和app混淆,所以称之为容器。
wsgi_middleware ,又称中间件,一种特殊类型的程序,专门负责在容器和应用进行额外处理的
具体wsgi app、wsgi container 和wsgi middleware关系的详细介绍请参看文章【1】
2 Odoo中的web运行机制
2.1 Odoo中的web server
Odoo自身定义实现了4中类型的web server,可以从server.py文件中得知
CommonServer是其他三个server的父类
Odoo运行的时候默认选择ThreadedServer作为其标准web server
2.2 Odoo中的web container
Odoo 中的web container在wsgi_server.py中定义
入口函数即为:
def application(environ, start_response)
通过判断在openerp-server.conf中是否定义代理模式proxy_mode和头信息“HTTP_X_FORWARDED_HOST”来判断是否代理请求,从而进行相应的处理
2.3 Odoo中的webhandler
在Odoo中,既然存在odoocontainer,那么必然存在用来处理具体request的handler,这个hander可以理解为容器中的一个具体的servelt
odoo的handler定义在http.py文件中
在运行的时候,通过调用odoo container的register_wsgi_handler方法将HandlerRoot注册到容器中,如下代码所示:
这个handler实现是充分利用werkzeug包进行二次封装,常见对象有reponse和request。具体werkzeug的内容请参见 http://werkzeug.pocoo.org/
2.3.1 Handler请求分发
1 对于Http请求
既然可以把handler当做java中的servlet,且Odoo中只有Root这样一个handler,那么可以推定Root必然要负责对所有外部来的请求进行分发处理,通过url映射到具体的controller中来进行处理,执行这个操作的就是Root类的dispatch函数
2 对于Http XML-RPC请求
则由http.py中的dispatch_rpc函数进行处理
2.3.2 Session的处理
Session对于web应用来说相当重要,在Odooo中,session类为OpenERPSession类,定义在http.py文件中
Session什么时候被创建?
在handler类初始化时,创建一个空的session对象,该对象并没有具体的值,如下图所示
当用户第一次登录或者访问系统时,Root类的dispatch方法被调用时被创建
Session 保存在什么地方?
Odoo中的session不是保存在内存中,而是保存在磁盘中,通过openerp.tools.config.session_dir参数设置保存地址,默认地址是在本地应用数据目录,以我的机子为例,默认的存放地址就是:C:\Users\janusx\AppData\Local\OpenERPS.A.\OpenERP\sessions\8.0
因此,我们可以通过设置openerp.tools.config.session_dir变量的值来改变odoo session保存的位置,可以是保存在本地或者结合Redis将Session保存到Redis中
Session 保存的时间是多少?
Odoo对于session的保存,默认是一周,对于超过一周的session,session_gc函数会将其从文件中移除,如下代码所示:
因此,我们可以通过自定义这个时间,来延长或者缩短Odoo的session的保存时间
2.4 Odoo web启动流程
通过以上分析,我们可知Odoo的启动流程,如下图所示