现在的位置: 首页 > 综合 > 正文

Session的工作原理

2013年09月10日 ⁄ 综合 ⁄ 共 5852字 ⁄ 字号 评论关闭

session的工作原理 一直在使用session存储数据,一直没有好好总结一下session的使用方式以及其工作原理,今天在这里做一下梳理。这里的介绍主要是基于php语言,其他的语言操作可能会有差别,但基本的原理不变。 1.在php中如何操作session: session_start(); //使用该函数打开session功能 $_SESSION  //使用预定义全局变量操作数据 使用unset($_SESSION['key']) //销毁一个session的值 简单地操作,一切都是由服务器实现;由于处理在后台,一切看起来也很安全。但是session采用什么样机制,又是怎样被实现,并且如何来保持会话的状态的呢? 2.session实现与工作原理 浏览器和服务器采用http无状态的通讯,为了保持客户端的状态,使用session来达到这个目的。然而服务端是怎么样标示不同的客户端或用户呢?这里我们可以使用生活中的一个例子,假如你参加一个晚会,认识了很多人,你会采取什么方式来区分不同的人呢!你可能根据脸型,也有可能根据用户的名字,或者人的身份证,即采用一个独一无二的标示。在session机制中,也采用了这样的一个唯一的session_id来标示不同的用户,不同的是:浏览器每次请求都会带上由服务器为它生成的session_id. 简单介绍一下流程:当客户端访问服务器时,服务器根据需求设置session,将会话信息保存在服务器上,同时将标示session的session_id传递给客户端浏览器,浏览器将这个session_id保存在内存中(还有其他的存储方式,例如写在url中),我们称之为无过期时间的cookie。浏览器关闭后,这个cookie就清掉了,它不会存在用户的cookie临时文件。以后浏览器每次请求都会额外加上这个参数值,再服务器根据这个session_id,就能取得客户端的数据状态。 如果客户端浏览器意外关闭,服务器保存的session数据不是立即释放,此时数据还会存在,只要我们知道那个session_id,就可以继续通过请求获得此session的信息;但是这个时候后台的session还存在,但是session的保存有一个过期时间,一旦超过规定时间没有客户端请求时,他就会清除这个session。 下面介绍一下session的存储机制,默认的session是保存在files中,即以文件的方式保存session数据。在php中主要根据php.ini的配置session.save_handler 来选择保存session的方式。 这里顺便说明一下,如果要做服务器的lvs,即多台server的话,我们一般使用memcached的方式session,否则会导致一些请求找不到session。一个简单的memcache配置: session.save_handler = memcache session.save_path = "tcp://10.28.41.84:10001" 当然如果一定要使用files文件缓存,我们可以将文件作nfs,将所有的保存session文件定位到一个地方。 刚才讲返回给用户的session-id最终保存在内存中,这里我们也可以设置参数将其保存在用户的url中。 3.实例问题现有系统A,B; 假设A系统是可以独立运行的web系统,即可以和浏览器直接处理session, B系统是基于mobile的,需要调用A系统的功能接口,在保持A不改变的情况下,即登陆验证,session存储都不变的情况下,B系统能处理前端用户的请求。 这里提供的方案是使用PHP实现 在用户登陆成功后,将保存的session的session-id返回给B系统,然后B系统每次请求其他接口都带session_id。A系统在session_start前加上session_id(session_id); 这样B系统就能安全的调用A

 

 

在ASP.NET的程序中要使用Session对象时,必须确保页面的@page指令中EnableSessionState属性是True或者Readonly,并且在web.config文件中正确的设置了SessionState属性。

  ASP.NET中Session的状态保持是由web.config文件中的标记下的标记的mode属性来决定的。该属性有四种可能的值:Off、Inproc、StateServer和SQlServer。

  设为Off会禁用Session。

  Inproc是缺省的设置,这种模式和以前的ASP的会话状态的方法是类似的,会话的状态会被保存在ASP.NET进程中,它的优点是显而易见的:性能。进程内的数据访问自然会比夸进程的访问快。然而,这种方法Session的状态依赖于ASP.NET进程,当IIS进程崩溃或者正常重起启时,保存在进程中的状态将丢失。

  为了克服Inproc模式的缺点,ASP.NET提供了两种进程外保持会话状态的方法。

  ASP.NET首先提供了提供了一个Windows服务:ASPState,这个服务启动后,ASP.NET应用程序可以将mode属性设置为“SateServer”,来使用这个Windows服务提供的状态管理方法。

  除了在web.config文件中设置mode属性为StateServer外,还必须设置运行StateServer服务器的IP地址和端口号.如果在IIS所在的机器运行StateServer则IP地址就是127.0.0.1,端口号通常是42424.配置如下:

  mode=”StateServer”

  stateConnectionString="tcpip=127.0.0.1:42424"

  使用这种模式,会话状态的存储将不依赖IIS进程的失败或者重启,会话的状态将存储在StateServer进程的内存空间中。

  另一种会话状态模式是SQLServer模式。这种模式是将会话的状态保存在SQL Server数据库中的。使用这种模式前,必须至少有一台SQL Server服务器,并在服务器中建立需要的表和存储过程。.NET SDK提供了两个脚本来简化这个工作:InstallSqlState.sql和UnInstallSqlState.sql。这两国文件存放在下面路径中:

  WinntMicrosoft.NETFramework

  要配置SQL Server 服务器,可以在命令行中运行SQL Server提供的命令行工具osql.exe

  osql -s [server name] -u [user] -p [password]

  例如:

  osql -s (local) -u as -p “”-i InstallSqlState.sql

  做好必要的数据库准备工作后,将web.config文件中的sessionstate元素的mode属性改为”sqlserver”,并指定SQL连接字符串。具体如下:

  mode="SQLServer"

  sqlConnectionString="data source=127.0.0.1;userid=sa;password=;Trusted_Connection=yes"

  使用SQLServer模式处了可以使Session的状态不依赖于IIS服务器之外,还可以利用SQL Server的集群,使状态存储不依赖于单个的SQL Server,这样就可以为应用程序提供极大的可靠性。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xuhui2000/archive/2009/01/21/3848278.aspx

 

我用document.cookie得不到ASP.NET_SessionId的值,但是用抓包软件却可以看到cookie中包含ASP.NET_SessionId=2p3l3u55tmcffnqbwziayq45;之类的数据,请问有什么办法得到ASP.NET_SessionId?

 

Application_Start是指网站重启等情况下第一次被人访问时激发的,通常可以定义一些全局变量到APPLICATION或CACHE中。而Session_Start是某个用户在某个会话期中第一次访问激发的,在这里通常啊可以设置某人的一些信息到SESSION,或触发用户访问计数等。
最常见的。在APPLICATION_START里设置APPLICATION["Count"]=0。然后在Session_Start里设置APPLICATION["Count"]++。

 

protected   void   Application_Start(Object   sender,   EventArgs   e)
{
Application[ "Application_Start "]= "A ";
}
 
protected   void   Session_Start(Object   sender,   EventArgs   e)
{
Application[ "Application_Start "]= "S ";
}

不是每次跳转页面都会触发 "Application_Start "和 "Session_Start "事件

你可以试一下..

private   void   Page_Load(object   sender,   System.EventArgs   e)
{
Response.Write(Application[ "Application_Start "].ToString());
Application[ "Application_Start "]= "M ";
Response.Write(Application[ "Application_Start "].ToString());
}

第一次运行的时候,输出SM  
因为Session_Start的application   把Application_Start的值给盖掉了.
刷新面一下.会输出MM

 

要说到session这个东西,很多人可能都不屑一顾。这个东东嘛,n年前就开始做了,有
啥好讲的啊。可是,在很多地方我们还是会发现一些问题,比如有的人说,我的
session_start激发了,怎么session_end没有啊,我在session_end做了些善后工作,
这下没法完成了,怎么办啊?

? 最近看了些文章,结合自己的一些经验,想和大家一起讨论一下其中的说法。

? 其实,很多这类的问题都是由一个东西引起的,它就是session ID。首先,是不是我
一个IE client起来,访问一个页面,只要我不关浏览器,session ID就是一样的呢?
很多人会想,应该是一样的吧,我浏览器都没关,web server总归会认为我是同一个
client,不会把session ID变来变去的。要验证这个,让我们现在做一个简单的试验。
用vs.net创建一个简单的asp.net web app.在web form1上加个button,然后在页面的
page prefix上enable trace.接下来浏览这个页面,不停的click button来提交
request。感谢asp.net的这个trace功能,我们可以看到session ID其实是在不停的变
化的。也就是说,这时候在服务器端,根本就不关心这个client的存在,每次都觉得它
是来自一个新的client.

? 那这到底是怎么回事呢?OK,让我们在page_load里面加上一句,
session["variable1"]="testvalue";然后再做一下测试。Bingo,现在session ID就保
持一致了。我想,很多人也许以前就没有注意到这点。这里我们可以得出一个结论:要
建立一个持续的session,咱们需要至少使用一下session变量,用行话来说,就是要至
少往session dictionary中写入一次。

? 不过,值得注意的是,这只是个必要条件,还不是充分条件。

? 在提到下一个必要条件前,我们先来弄清一件事,如果我们在程序中间有
global.asax,里面有session_onstart, session_onend,上面的实验是不会成功的。原
因是一旦定义了session_onstart处理函数后,session的state就总是会被保存了,即使
里面是空的,这样的话,session ID就不会改变了。因为session这东西还是消耗资源
的,所以在asp.net web app中如果没有必要,你就不要把session_onstart,
session_end写在global.asax中。

? 上面的实验中,我们也可以看到,如果session ID在变化,我们就跟踪不到
session_onend,一旦稳定下来,session_onend就出现了。

? 现在,我们再来谈谈另一个条件,还是先从实验做起,我们在刚才例子的基础上(包
括session_onstart, session_onend),在page_load的session那行的下面加上一句,
session.abandon().再来运行一把,咦,这是你会发现一点奇怪的地方,session_onend不
执行了,尽管session_onstart执行过了一遍。(这里我们需要写一些log语句来观察
到)而且,如果我们把session.abandon()写在button.onclick事件里面,
session_onend就立马执行了。奇怪吧,这里有什么区别呢?

? 这样,第二个必要条件就引发了,要让session_onend成功执行,至少要有一个
request已经被完整地执行过。上面的第一种情况,在page_load中就中止的话,第一个
request都没有执行完毕,session_onend就没法激发了。

? 综合这两个必要条件,我们终于可以得出要让session_onend执行的充分条件了:
? 1)至少有一个request成功完整地执行
? 2)至少存储一些data在session state中。可以通过session变量或者加上
session_onstart来实现。

? 最后声明一点,session_onend只在InProc模式中支持,也就是说,只在session
data在asp.net worker process中时支持。

 

Application_End事件的触发时机

修改web.config   ->    造成应用程序重启   
重启应用程序池
重启IIS

 

 

 

 

 

 

抱歉!评论已关闭.