`
qqsunkist
  • 浏览: 32997 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

cppcms中的session

 
阅读更多

问题:

如果打开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丢失的解决办法

    在探讨“IFrame中Session丢失的解决办法”这一主题时,我们首先需要理解Session与IFrame的基本概念及其在Web开发中的交互方式。Session是Web应用中用于存储用户特定信息的一种机制,它允许开发者在用户的会话期间...

    asp.net c# 在类中使用session的方法

    在ASP.NET中,Session是一种服务器端的存储技术,用于跟踪用户会话状态,保存特定于用户的变量或对象。在Web应用程序开发中,特别是在ASP.NET C#应用中,正确且有效地在类中使用Session是非常重要的,这能帮助我们...

    hibernate中session的管理

    在Hibernate框架中,Session是与数据库交互的主要接口,它负责对象的持久化操作。然而,由于Session不是线程安全的,所以在多线程环境中管理Session就需要特别注意。本篇文章将详细探讨Hibernate中Session的管理,...

    设定tomcat中session过期时间.txt

    ### 设定Tomcat中Session过期时间的三种方式 在Web开发中,Session管理是确保用户状态跟踪的重要机制之一。Tomcat作为一款广泛使用的Java应用服务器及Servlet容器,提供了多种方式来设定Session的有效时长。这有助...

    jsp中session的用法详解

    "jsp中session的用法详解" jsp 中 session 的使用方法可以帮助开发者追踪用户的操作过程,而不需要担心追踪的实现细节。Session 是一种服务器端的机制,用于存储用户的信息,以便在多个页面之间共享数据。 在 jsp ...

    详解SpringBoot中Session超时原理说明

    SpringBoot 中 Session 超时原理说明 在 SpringBoot 中,Session 超时是指在一定时间内没有任何操作,Session 就会超时失效,导致用户需要重新登录才可以继续访问页面。这是因为 Session 的超时时间是有限制的,...

    自己实现的spring-session

    如果没有sessionId就新创建session,如果有sessionId,就去redis中查看是否有此id的记录,如果没有就新建session,如果有,还是新建session,并把redis中此session的相关数据赋值给新建的session,最后保存sessionId...

    请问ASPX中如何读取SESSION变量

    ### ASPX中如何读取SESSION变量 在ASP.NET Web应用程序中,`Session`对象是非常重要的一个组成部分,它用于存储特定用户会话所需的属性及配置信息。`Session`对象中的数据只对当前用户可见,并且在用户浏览网站的...

    jsp中session使用方法

    ### jsp中session使用方法详解 #### 一、引言 在Web开发中,会话管理是一项非常重要的功能,特别是对于需要保持用户状态的应用程序来说更是如此。在Java Web开发中,`HttpSession`接口提供了在多页面请求之间保存...

    jsp中Session对象源码

    在JavaServer Pages (JSP) 技术中,`Session` 对象是一个非常重要的概念,它用于跟踪用户会话状态。在Web应用中,当用户访问网页时,服务器可能需要记住用户的一些信息,如购物车内容、登录状态等,这时就需要用到...

    jsp中存取session值简单介绍

    在JSP(Java Server Pages)技术中,session是一种用来跟踪用户状态的机制。由于Web应用通常是无状态的,即每次用户发送请求到服务器,服务器端并不记得这个用户之前的操作,因此为了保持用户的登录状态或者其他信息...

    NET的csharp的session丢失sessionid不一样

    ### 关于.NET中C# Session丢失与SessionID变化问题解析 #### 一、问题背景及概述 在.NET框架中,特别是在使用C#进行Web开发时,Session管理是至关重要的一个环节。Session对象允许服务器存储有关用户会话的信息,...

    session session session szsessdifn

    在Web开发中,Session是一个至关重要的概念,尤其是在ASP.NET框架下。Session机制是服务器端存储用户特定信息的一种方式,它允许开发者在多个页面之间保持用户状态,解决了HTTP协议无状态的问题。"szsessdifn"可能是...

    JSP中session的使用详解

    ### JSP中Session的使用详解 #### Session概念与作用 在Web开发中,`Session`是一种用于维护客户端与服务器之间会话状态的技术。不同于HTTP协议的无状态特性,`Session`使得服务器能够识别并追踪特定用户的状态,...

    java中使用session模拟用户登陆

    在Java Web开发中,Session是服务器端用于跟踪用户状态的一种机制。当用户通过用户名和密码登录系统后,服务器需要一种方式来识别这个已验证的用户,以便在后续的请求中提供个性化的服务,例如访问权限控制。这时,...

    hibernate中session对象的状态详解

    hibernate中session对象的状态详解

    servlet中关于session的理解

    ### 关于Servlet中的Session理解 在Web开发领域中,Servlet技术是Java Web开发的重要组成部分,而Session机制则是处理用户会话的关键技术之一。本文将基于提供的文件内容,深入探讨Servlet中Session的工作原理、...

    在WEB API中启用session

    在Web API中启用Session涉及到的是将传统的Web应用程序中的会话状态管理应用到API设计中。Web API通常是无状态的,因为它遵循RESTful架构原则,但有时我们可能需要在某些场景下存储客户端的状态信息,这时就需要考虑...

    PHP中session全面教程

    - **数据管理:**服务器端可以将用户的特定信息存储在Session变量中,例如用户的登录状态、购物车中的商品等。 #### 二、Session在PHP中的实现 在PHP中,Session的实现相对简单且高效,下面我们将详细介绍如何在...

    java中使用session购物车的简单例子

    在本例中,“java中使用session购物车的简单例子”是通过Servlet技术实现的一个应用场景,旨在帮助开发者理解如何利用Session来存储用户购物车的数据。 购物车功能在电商网站中非常常见,它允许用户临时保存想要...

Global site tag (gtag.js) - Google Analytics