Session 详解

 

Session 详解

引子

想一个问题, 有一个商店要作一个活动,对于在本店累计消费超过2000元的客户 ,能够领取小礼品一份。要如何实现 。php

  1. 每次消费给客户一张消费凭证如发票等 ,用户兑奖把这些发票都带过来 。
  2. 给客户办一张会员卡,客户结帐时出示会员卡,收银员能够在商店的管理系统查到客户的历史消费记录 ,而后兑奖。

是什么

字面意思 会话(对话) ,会话机制 ,客户端发起对话,服务端回答,通过屡次对话后,让服务端拥有知道以前和某个客户聊了什么的机制 。java

其余web

  • session 是一种服务端机制 ;
  • 由于http协议无状态,全部须要状态管理 ( 记得上一讲 ,为何有cookie 也是这个缘由么 );
  • 不一样web平台都有对session机制的实现;

创建会话:redis

客户端请求服务端,服务端检测这边有没有存储和这个客户的对话。若是没有就创建会话 ,有的话继续维护当前会话。(思考问题,经过什么检测有没有和这个客户的对话)算法

断开会话:sql

服务端销毁某个会话数据,会使其断开;客户端长时间不访问服务端,根据配置的session过时时间,服务端会销毁和某个客户端会话数据。
同时,客户端也能够断开会话,只须要客户端不告诉服务端sessionid,或者换一个开启一段新的会话。数据库

分清楚一个概念:会话状态和登陆状态的区别

会话状态虽然经常被用来标识登陆状态。可是却不能彻底等同 ;登陆状态很好理解,用户没有登陆以前,是未登陆状态。 输入帐号密码(或其余方式)登陆验证成功以后是 已登陆状态。
那何时开始有会话状态的呢 ?
举一个例子来证实没有登陆,会话状态已经产生了 :好比登陆或者注册时的图形验证码 。c#

不一样web平台中对session的实现

不一样web开发框架都有对session机制的 实现,或者叫封装 ,常见的平台以下图:windows

平台 核心对象 默认存放sessionId的cookie name 使用语法
c# System.Web.SessionState.HttpSessionState ASP.NET_SessionId Session[""]=3;
php $_SESSION PHPSESSID $_SESSION['33']=1;
java javax.servlet.http.HttpSession JSESSIONID HttpSession session = request.getSession(); session.setAttribute("data", "sfe");

Asp.net 对Session的实现

咱们从Session在web.config文件中的配置讲起:参考跨域

  • session在web.config中的配置
<sessionState
mode= "[Off|InProc|StateServer|SQLServer|Custom]"
timeout= "number of minutes"
cookieName= "session identifier cookie name"
cookieless=
"[true|false|AutoDetect|UseCookies|UseUri|UseDeviceProfile]"
regenerateExpiredSessionId= "[True|False]"
sessionIDManagerType= "session manager type"
sqlConnectionString= "sql connection string"
sqlCommandTimeout= "number of seconds"
allowCustomSqlDatabase= "[True|False]"
useHostingIdentity= "[True|False]"
stateConnectionString= "tcpip=server:port"
stateNetworkTimeout= "number of seconds"
customProvider= "custom provider name"
compressionEnabled= "[True|False]"
sqlConnectionRetryInterval= "number of seconds">
<providers>... </providers>
</sessionState>

挑几个关键属性讲下:

  • mode
    • Off: 关闭,不使用cookie
    • InPro: 当前进程,也就是w3wp进程
    • SQLServer :会话状态正在使用进程外 SQL Server 数据库存储状态信息。Aspnet_regsql.exe 工具
    • StateServer:会话状态将使用进程外 ASP.NET 状态服务来存储状态信息, windows服务aspnet_state.exe
    • Custom : 自定义,本身实现SessionStateStoreProviderBase这个抽象类就能够了,而后配置:
<sessionState mode="Custom" customProvider="MySessionStateStore">
<providers>
<clear/>
<add name="MySessionStateStore" type="Microsoft.Web.Redis.RedisSessionStateProvider" connectionString="RedisConnection"/>
</providers>
</sessionState>
  • cookieless
    • AutoDetect :session机制根据浏览器对cookie的支持状况决定是使用cookie仍是url传递sessionid
    • UseCookies :显式指定使用cookie 传递sessionid【推荐
    • UseDeviceProfile :session机制根据浏览器对cookie的支持状况决定是使用cookie仍是url传递sessionid
    • UseUri: 显式指定用url传递sessionid

常见Session丢失缘由

一、Session超时,用户打开页面,页面长时间不操做会致使此缘由

二、IIS应用程序池回收,或者重启

三、Web.Config修改,即IIS应用程序池重启

四、dll被替换或者动态页面修改,即IIS应用程序池重启

五、杀毒软件对.config文件进行扫描,可能会致使IIS应用程序池回收

六、用户浏览器禁用cookie

七、其余缘由

asp.net Session 进阶

Session 共享

两个网站会话共享, a网站登陆,b网站也登陆了,根据session的原理 ,session是经过客户端的cookie里的sessionid 来识别同一个用户发来的请求,因此这里这里就是要连个网站sessionid同样 ,也就是cookie相同,可是cookie是不能跨域传输的,可是只要主域同样 ,将cookie的域设置成domain.com ,cookie会发送到这个主域下全部子域对应的网站。
是否发送到两个网站服务端的sessionid同样,session就共享了呢,其实否则 ,
若是session mode 是Inpro 模式,这明显不行,由于session存在各自的网站进程里面,
若是session mode是 stateServer模式呢 ,其实也不行,须要进行一些小修改就好,由于session的存储结构不仅仅是 sessionid 和session里面的内容 ,他是sessionid 和网站惟一标志共同来惟一指定的,咱们能够经过一些手段骗session机制,两个不一样的网站的惟一标志是同样的。
session mode 是sqlserver 和上面的方案差很少,也是要进行些修改,让网站标志同样 。
能够看到实现session的共享仍是很麻烦的。

  1. 设置存储sessionid的cookie的域是主域
  2. 将session存在 stateserver 或者sqlserver (性能会有所影响) ,
  3. 骗asp.net session机制,不一样网站的网站惟一标志是同样的。

网站负载了 Session 还可用么

这个问题还须要有负载均衡相关知识才能了解,简而言之,一样的web程序部署多个,客户端发出的请求根据算法分配到其中某一个服务端处理。
首先能够肯定,发送到多个程序的sessionid是同样的,接着就是服务端能根据sessionid获取到一样的会话数据吗?
这个问题和上面很像 ,是不能的,由于网站的标志不同的。说解决方案也和上面差很少了,少了第一步。

Session 的并发缺点

微软官方的几种sessionmode provider 都有这个问题,在一段会话里面 ,服务端会按照循序处理客户端发过来的会话请求 ,也就是说,上一个请求没处理完,浏览器就发起了下一个请求的话会被挂起,直到上一个会话请求处理完成。这种并发状况可能常见于一个页面上对服务端发出多个异步请求,若是某个请求处理时间很长 ,后面就请求就会被挂起。虽然.net 提供了关闭某个地址session的配置,可是一般业务场景中都是须要会话状态的。

不用Asp.net Session 用什么

咱们把这个问题转换一下,由于

常见的session使用场景是

  1. 存储验证码
  2. 存储用户基础信息,如id ,姓名,角色等
  3. 做为身份验证,登陆验证
  4. 多个页面间传值
  5. ???

那么就是找处处理这些场景问题解决方案就能够了 。
能不能把用cookie加密存储。 或者cache +cookie ,redis +cookie ,
另外身份验证能够用。net自带 forms 身份验证。

Q&A

  1. 为何session(若是做为登陆状态,那就会形成从新登陆)莫名其妙丢失 ?
  2. 向session里面写数据时报错 ,没法序列化
    没法序列化会话状态。在“StateServer”或“SQLServer”模式下,ASP.NET 将序列化会话状态对象,所以不容许使用没法序列化的对象或 MarshalByRef 对象。若是自定义会话状态存储在“Custom”模式下执行了相似的序列化,则适用一样的限制。
  3. 用来承载会话的cookie ,有什么特征。
  4. 若是让你实现一个简单的session机制须要作哪些事 。
相关文章
相关标签/搜索