问题:
如果打开cppcms的reference文档,在吹泡泡cms::sessions namespace下存在如下几个类:
class encryptor; // 泛型session cookies 加密接口.
class encryptor_factory; // 顾名思义,建立新加密器的接口
class session_cookies; // 使用加密的或者签名的cookies的session_api实现。
class session_dual; // session_api的客户端和服务器端存储实现
class session_sid; // 用session_storage和唯一session id存储session数据的session_api实现。
class session_server_storage //是一个允许用户实现自定义session storage(如数据库)的抽象类。
class session_storage_factory //建立session storage对象的工厂类。
但是session_cookies, session_dual, 和session_sid三个实现的接口类session_api却不在cppcms::sessions namespace下,另外,在cppcms::application调用的session()返回的session_interface类引用也同样不在namespace下。在service中定义的session_pool也不在此命名空间内。为什么呢?这几个类虽然都跟session有关系,互相之间又是如何关联的呢?
小结:
打开service.cpp浏览代码,先看构造函数service::service(int argc,char *argv[]) :
impl_(new impl::service())
{
impl_->args_.assign(argv,argv+argc); //pimp idiom, args的类型vector<std::string>
json::value val = load_settings(argc,argv); //读取并解析config.js中的json配置参数
impl_->settings_.reset(new json::value()); //重置
impl_->settings_->swap(val); //按照config.js的配置修改Impl的设定。
setup(); //安装service.
}
再看setup成员函数
void service::setup()
{
impl_->cached_settings_.reset(new impl::cached_settings(settings()));
impl::setup_logging(settings());
impl_->id_=0;
int reactor=reactor_type(settings().get("service.reactor","default"));
impl_->io_service_.reset(new io::io_service(reactor));
impl_->sig_.reset(new io::stream_socket(*impl_->io_service_));
impl_->breaker_.reset(new io::stream_socket(*impl_->io_service_));
int apps=settings().get("service.applications_pool_size",threads_no()*2);
impl_->applications_pool_.reset(new cppcms::applications_pool(*this,apps));
impl_->views_pool_.reset(new cppcms::views::manager(settings()));
impl_->cache_pool_.reset(new cppcms::cache_pool(settings()));
impl_->session_pool_.reset(new cppcms::session_pool(*this));
if(settings().get("file_server.enable",false)) {
applications_pool().mount(applications_factory<cppcms::impl::file_server>(),mount_point(""));
}
}
这个成员函数执行过程中,在倒数第二步重置了session_pool. 当扮演controller角色的application main函数调用app.run()函数后,cppcms后面又做了什么跟session相关的动作呢?我们且再看下run成员函数。
void service::run()
{
run_prepare(); //->依次调用函数generator(), forwarder(), session_pool().init(), start_acceptor().
impl::daemonizer godaemon(settings());
if(prefork()) { // prefork() 用以设置系统signal及handler
return;
}
thread_pool(); // make sure we start it
if(impl_->prefork_acceptor_.get())
impl_->prefork_acceptor_->start();
after_fork_exec();
run_acceptor();
setup_exit_handling();
run_event_loop();
}
根据上述代码,我们再继续查看session_pool.cpp代码中的init成员函数
void session_pool::init()
{
service &srv=*service_;
if(backend_.get())
return;
std::string location=srv.settings().get("session.location","none");
if((location == "client" || location=="both") && !encryptor_.get()) {
... ...
}
if((location == "server" || location == "both") && !storage_.get()) {
... ...
}
if(location == "server") {
std::auto_ptr<session_api_factory> f(new sid_factory(this));
backend(f);
}
else if(location == "client") {
std::auto_ptr<session_api_factory> f(new cookies_factory(this));
backend(f);
}
else if(location == "both") {
unsigned limit=srv.s.ettings().get("session.client_size_limit",2048);
std::auto_ptr<session_api_factory> f(new dual_factory(limit,this));
backend(f);
}
else if(location == "none")
;
else
throw cppcms_error("Unknown location");
service_->after_fork(boost::bind(&session_pool::after_fork,this));
}
不过上述代码比较冗长一些,但是还好,逻辑看起来还是比较清晰的。顺序上,大致是如下逻辑;
1. 判断是否已经有session了?如果有,返回。
2. 如果1.没有,则根据config.js中session section的配置,进行各种scenario的判断和处理;
I. session存放在client端或者both(既存放在client端也存放在server端),同时没有配置encryptor
II. session存放在server端或者both,但没有配置session storage
III. session只存放在server端,那么通过sid_factory创建session_sid
IV. session只存放在client端,那么通过cookies_factory创建session_cookies
V. session存在在both端,那么通过dual_factory创建session_dual
VI. session的location如果是none, 啥也不做。
VII. 其他情况,抛出unknown location异常。
针对scenario I, II, 还有进一步的处理,此处忽略。
从上述的各种scenario处理情况来看,逻辑上大致分三种情况,即
1. 如果存放在client端的话,必须对session存放的数据按照配置的加密算法进行加密。
2. 如果存在server端的话,server负责产生一个session id.
3. 如果存在both端的话,session_sid, session_cookies都需要被创建。
这样我们可以看出cppcms中有关session的一些端倪了。实际上,session_pool是cppcms框架中用来管理session的核心组件,session_pool中包含了三个auto_ptr,分别指向session_api_factory, encryptor_factory和session_storage_factory。session_api_factory用以创建实际操作session的类。根据不同的操作,cppcms中一共有三种session操作类,它们是session_cookies, session_sid, session_dual。session_storage_factory用以创建针对不同s媒介的storage,包含memory, cookie, database, network等。encryptor_factory主要创建加密器用以针对存储在客户端的session数据应该实施必要的加密措施。
那么上述的那三个session操作类,操作对象是什么呢?当然是session了!对,不过在cppcms里,session是被封装在session_interface中的。
之所以没有把session_api, session_interface, session_pool这三个类放在cppcms::sessions namespace下,个人认为可能是作者有意想把跟http session在框架中独立出来,放在了cppcms域中。而组成session_pool的核心组件类才被放入到cppcms::sessions域中。
分享到:
相关推荐
在探讨“IFrame中Session丢失的解决办法”这一主题时,我们首先需要理解Session与IFrame的基本概念及其在Web开发中的交互方式。Session是Web应用中用于存储用户特定信息的一种机制,它允许开发者在用户的会话期间...
在ASP.NET中,Session是一种服务器端的存储技术,用于跟踪用户会话状态,保存特定于用户的变量或对象。在Web应用程序开发中,特别是在ASP.NET C#应用中,正确且有效地在类中使用Session是非常重要的,这能帮助我们...
在Hibernate框架中,Session是与数据库交互的主要接口,它负责对象的持久化操作。然而,由于Session不是线程安全的,所以在多线程环境中管理Session就需要特别注意。本篇文章将详细探讨Hibernate中Session的管理,...
### 设定Tomcat中Session过期时间的三种方式 在Web开发中,Session管理是确保用户状态跟踪的重要机制之一。Tomcat作为一款广泛使用的Java应用服务器及Servlet容器,提供了多种方式来设定Session的有效时长。这有助...
### ASPX中如何读取SESSION变量 在ASP.NET Web应用程序中,`Session`对象是非常重要的一个组成部分,它用于存储特定用户会话所需的属性及配置信息。`Session`对象中的数据只对当前用户可见,并且在用户浏览网站的...
"jsp中session的用法详解" jsp 中 session 的使用方法可以帮助开发者追踪用户的操作过程,而不需要担心追踪的实现细节。Session 是一种服务器端的机制,用于存储用户的信息,以便在多个页面之间共享数据。 在 jsp ...
SpringBoot 中 Session 超时原理说明 在 SpringBoot 中,Session 超时是指在一定时间内没有任何操作,Session 就会超时失效,导致用户需要重新登录才可以继续访问页面。这是因为 Session 的超时时间是有限制的,...
如果没有sessionId就新创建session,如果有sessionId,就去redis中查看是否有此id的记录,如果没有就新建session,如果有,还是新建session,并把redis中此session的相关数据赋值给新建的session,最后保存sessionId...
### jsp中session使用方法详解 #### 一、引言 在Web开发中,会话管理是一项非常重要的功能,特别是对于需要保持用户状态的应用程序来说更是如此。在Java Web开发中,`HttpSession`接口提供了在多页面请求之间保存...
在JSP(Java Server Pages)技术中,session是一种用来跟踪用户状态的机制。由于Web应用通常是无状态的,即每次用户发送请求到服务器,服务器端并不记得这个用户之前的操作,因此为了保持用户的登录状态或者其他信息...
### 关于.NET中C# Session丢失与SessionID变化问题解析 #### 一、问题背景及概述 在.NET框架中,特别是在使用C#进行Web开发时,Session管理是至关重要的一个环节。Session对象允许服务器存储有关用户会话的信息,...
在.NET Core 6中,开发人员可以利用Session来实现用户验证功能,这在构建Web应用程序时至关重要,确保了用户安全和个人信息的保护。Session是一种在服务器端存储用户状态信息的方法,使得在多个请求之间保持数据成为...
在Web开发中,Session是一个至关重要的概念,尤其是在ASP.NET框架下。Session机制是服务器端存储用户特定信息的一种方式,它允许开发者在多个页面之间保持用户状态,解决了HTTP协议无状态的问题。"szsessdifn"可能是...
### JSP中Session的使用详解 #### Session概念与作用 在Web开发中,`Session`是一种用于维护客户端与服务器之间会话状态的技术。不同于HTTP协议的无状态特性,`Session`使得服务器能够识别并追踪特定用户的状态,...
在Java Web开发中,Session是服务器端用于跟踪用户状态的一种机制。当用户通过用户名和密码登录系统后,服务器需要一种方式来识别这个已验证的用户,以便在后续的请求中提供个性化的服务,例如访问权限控制。这时,...
hibernate中session对象的状态详解
### 关于Servlet中的Session理解 在Web开发领域中,Servlet技术是Java Web开发的重要组成部分,而Session机制则是处理用户会话的关键技术之一。本文将基于提供的文件内容,深入探讨Servlet中Session的工作原理、...
在Web API中启用Session涉及到的是将传统的Web应用程序中的会话状态管理应用到API设计中。Web API通常是无状态的,因为它遵循RESTful架构原则,但有时我们可能需要在某些场景下存储客户端的状态信息,这时就需要考虑...
- **数据管理:**服务器端可以将用户的特定信息存储在Session变量中,例如用户的登录状态、购物车中的商品等。 #### 二、Session在PHP中的实现 在PHP中,Session的实现相对简单且高效,下面我们将详细介绍如何在...
在本例中,“java中使用session购物车的简单例子”是通过Servlet技术实现的一个应用场景,旨在帮助开发者理解如何利用Session来存储用户购物车的数据。 购物车功能在电商网站中非常常见,它允许用户临时保存想要...