node模拟http服务器session机制-我们到底能走多远系列(36)
2013-12-23 20:25
281 查看
我们到底能走多远系列(36)
扯淡:年关将至,总是会在一些时间节点上才感觉时光飞逝,在平时浑浑噩噩的岁月里都浪费掉了太多的宝贵。请珍惜!
主题:
我们在编写http请求处理和响应的代码的时候,经常会处理到session,这里的session是指服务器和客户端交互时把一些信息存在服务器上,下一次请求是,可以在服务器上继续使用这些信息,我们都知道http是无状态的,在服务端维持一个session就是为了解决一些多个请求需要状态维持的问题。
它的工作原理,我的理解是,在第一次http请求时,服务端在自己内存里创建出一个对应这个客户端的session,往这个session中放好信息后,把标识这个session的唯一字段在响应的时候带给客户端,客户端将这个字段放入cookie,下一次请求的时候客户端就会把这个cookie信息带上来,服务端就可以找出这个客户端对应的session了,也就可以重新使用原来保存的信息。
这个工作是web容器完成的,像tomcat,jetty, weblogic 都实现了对session相关的接口。
比如说遇到这样的问题:多个容器分布部署的时候,web容器中的session无法共享,这样可以不把session的信息部存在内存中,而是存在类似redis,memcache这样的数据库中。这样就需要重写处理session的逻辑。修改web容器的源码,或者自己实现以下存取session,和传输解析cookie的方法来模拟session。
java编码中的使用:
HttpSession session = request. getSession(); session.setAttribute ("uid", 1) ; session.getAttribute ("uid") ;
从原理上来看,实现的流程很清晰,在用node实现web应用的时候,现在流行用express.js。不使用框架的session接口的话,我们自己也可以粗糙的实现一下:
// 获得客户端的Cookie var Cookies = {}; req.headers.cookie && req.headers.cookie.split(';').forEach(function( Cookie ) { var parts = Cookie.split('='); Cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim(); }); console.info(Cookies); // 设置cookie res.setHeader( 'Set-Cookie', 'myCookie=test' );
利用上面的获取cookie和设置cookie,还不能完全完成session维护的流程。还需要服务端存取session值。
实际上我们在开发普通的web项目的时候,可以了解到,对每一个客户端,服务端都会维护一个session,这些session中存着一些键值对,就像前面jsva代码中看到的,"uid"对应1,然后来查的时候就利用cookies中带上来的id,找到session,再从这个session中查有没有'uid'对应的1。
那么,下面就简单用js来实现一个登录进入一个下载页面,来模拟http session的机制。
流程类似如下:
var Session = function(opt){ if(opt){ this.id = opt.id; this.overLifeTime = opt.expires; } }; module.exports = Session;
View Code
看了SessionManage的代码,只要在登录的时候调用一下setSession,然后再过滤器上调用下getSession,就可以完成上面的流程了。使用express,虽然它自带了session机制,没有使用,模拟过滤器的代码实现在app.js中的:
// 正则匹配全部请求 app.get(/^\/*/,function(req, res, next){ if(req.path == "/upload" || req.path == "/doupload"){ var user = SessionsManage.getSession(req,"user"); if(!user){ res.render('login', {}); return; } } next(); });
登录的时候:
exports.dologin = function(db, sessions){ return function(req, res) { console.log("dologin"); var username = req.body.username; var password = req.body.password; console.log("username:" + username + "password:" + password); var collection = db.get('usercollection'); collection.find({},{'username':username,'password':password},function(e,docs){ if(docs){ console.log("username and password is valid"); var opts = { name : "user", value : username, expires : 500 }; // 调用了setSession sessions.setSession(req,res,opts); res.render('upload', {}); }else{ console.log("username and password is invalid"); } }); }; };
以上就基本走完了流程,只要使用express进行一些请求上的配置,就可以了。主要是sessionManage中的实现,用提供出去的几个方法来模拟了整个机制。
另外,还有一些不足的地方,和遗留的漏洞。
让我们继续前行
----------------------------------------------------------------------
努力不一定成功,但不努力肯定不会成功。
相关文章推荐
- 学习java中的几个Map-我们到底能走多远系列(27)
- InternalInputBuffer处理HTTP请求行-Tomcat源码-我们到底能走多远系列(11)
- 当你想在web应用中使用线程的时候-我们到底能走多远系列(24)
- Tomcat加载servlet类文件 -我们到底能走多远系列(9)
- 请求路由到业务方法设计(2)-我们到底能走多远系列(45)
- Java NIO基础 -我们到底能走多远系列(17)
- 关于ibatis批量问题-我们到底能走多远系列(26)
- 利用spring AOP 和注解实现方法中查cache-我们到底能走多远系列(46)
- 搭建服务器处理系统(基于netty)-我们到底能走多远系列(25)
- BufferedInputStream-我们到底能走多远系列(3)
- 图片上传+预览+剪切解决方案-我们到底能走多远系列(20)
- 文件下载-excel导出-我们到底能走多远系列(22)
- How Tomcat Works 学习-我们到底能走多远系列(8)
- 我们到底能走多远系列(13)
- cglib源码主流程源码-我们到底能走多远系列48
- 我们到底能走多远系列
- 剪切文件_配置文件修改-我们到底能走多远系列(4)
- 图片尺寸判断等-我们到底能走多远系列(21)
- Sharded实现学习-我们到底能走多远系列(32)
- 服务调用方案(Spring Http Invoker) - 我们到底能走多远系列(40)