今天终于使用nodejs+redis把网页版即时聊天框架zenkim搭了起来,非常简陋,不过登录/用户管理/实时消息推送/消息缓存/用户单实例登录控制deng基本能力都有,待完成的功能包括:消息持久化及活动用户队列周期扫描/加强事务能力/消息排序/界面美化/移动版本支持。再优化一下后放到github上。
今天花了一下午时间,都用在了处理session上。nodejs本身不管session,因为用了express框架,express基于connect,connect中有session管理的能力。connect是插件式架构,它的插件称之为“中间件”,其中有个中间件就是叫作session。
使用express命令搭建应用框架时,加上-s选项,就可以添加对session的支持,之后在url映射函数中,直接使用req.session就可以访问和添加session信息。
问题是这样的:为了浏览器兼容,zenkim使用long polling方式实现实时消息推送。这就要求除了正常的浏览器请求链接外,还有一个后台链接用作推送消息,该链接的response对象能够长期(几秒到几分钟)保存在后台。开始时将response对象保存在了session中(当然,后来发现这么做不合适,并且有错),但发现后台链接session中的对象,在正常浏览器请求的session中看不到。不是同一个浏览器看到的session数据应该是同一份吗?为什么出现这种情况?
后来还是看了session这个connect中间件的代码才了解原委。session保存在称为sessionStore的数据仓库中。默认使用MemoryStore,就是所有session信息都保存在内存中。每来一个请求后,在路由分发前,首先使用cookieParser中间件将cookie中的sessionID解析出来,然后根据sessionID去sessionStore中进行查找,如果找到一份session后,就使用sessionStore中的数据构建一个新的session对象,把这个session对象放到req.session中,这就是session的由来。
另外,session中间件还改写了res.end方法,在将应答发送回浏览器之前,先将session数据写回sessionStore。
从实现过程可以看出:
1. 每个session对象都是针对某一个http请求的,每个请求的session对象相互独立,互不影响。
2. 在没有调用res.end之前,session对象不会回写到sessionStore中,除非主动调用了session.save方法。
3. session的解析依赖cookieparser,因此cookieparser中间件应该放到session之前。路由处理函数依赖session数据,因此app.router中间件应该放到session之后
4. 因每个请求有独立的session对象,因此对于同一个客户端有多个链接的情况,需要考虑session回写的并发问题。
所以在将res对象放到后台请求的session中后,同一时刻前台请求的session中是看不到这个res对象的。可以在放置了res之后,立刻调用session.save方法将信息保存回sessionStore,此时前台请求才可能看到。
不过这里要是调用session.save的话会报错,说session数据有循环依赖,无法保存回sessionStore。实际上是session数据如果有循环依赖的话,无法使用JSON.stringify转化为字符串,而memorystore使用字符串保存session数据,所以会出错。
解决办法是将res保存到内存中的一个临时数据结构中。这个res中有大量链接/socket/应用/请求信息,的确不适合保存到session中,另外res只是一个临时的链接数据,缓存在内存即可,也的确不应该放到session中。而将res放到内存中,所有请求都可以看到,这时会有并发问题。谢天谢地,node.js是单线程的,虽然一堆回调让代码不知什么时间会运行,但至少同一个函数中代码的前后顺序还是可以保证的,中间不会插入执行其他代码,函数内部保证数据访问的一致性就好了。
2015-11-7 update:
刚才搜索一个nodejs session管理的问题,没想到搜到自己三年前写的这篇文章。其中的很多内容都过时了,比如express现在和connect合在一起了,session管理也不依赖cookieParser中间件了,不过其中有些关于express和nodejs处理的内容还是有部分价值的。
另外zenkim项目后来改为webim,已经停止开发了。当时对nodejs的callback hell深恶痛绝,最后切换到使用erlang实现了相同的IM功能,web部分使用mochiweb,消息队列部分使用rabbitmq直接管理消息队列,整个IM功能做成了rabbitmq的一个插件,改名为rabbitmq-webim,已经在线运行两年了,基本没什么问题。源码在github上(https://github.com/zenkj/rabbitmq-webim)。
最近nodejs越来越红火,拿过来重新写了几个应用,发现使用async.js时callback hell也没什么不可忍受的,并且与erlang的变量不可变一样,可以逼着你写很多小函数,实际上能让代码更好维护,所以nodejs还是不错的。
相关推荐
基于nodejs+mysql实现的仿京东商城...Cookie-Parser、Cookie-Session进行cookie与session的处理 首页数据的展示 分类页数据的展示 购物车 我的 注册 登录 商品详情页 商品搜索 mysql数据库的安装 运行详情见包内文档
使用NodeJs的express框架完成电影网站后端搭建; 使用mongodb完成数据存储,通过mongoose模块完成对mongodb数据的构建; 使用jade模板引擎完成页面创建渲染; 使用Moment.js格式化电影存储时间; 3、本地开发环境...
之前看了一本nodejs的书,因为版本问题在制作demo的时候出现很多不兼容的情况。现在这个版本经调试是兼容最新的包
一个简单的NodeJS + 网站都已设置好,并准备使用和进行用户名+密码身份验证,使用持久性本地cookie,通过和View模板的和持久性会话使用 。 概述 该站点包括需要身份验证的登录页面,注册页面和索引页面,并且使用...
本项目是一个利用nodejs.socket.io实先的多人会议画板功能。实现会议同步,插入图片,插入线条,更换背景色,和移动端兼容等。若有不足之处望批评。谢谢
本篇文章主要介绍了Nodejs进阶:express+session实现简易身份认证示例,非常具有实用价值,需要的朋友可以参考下
NodeJS之ExpressSession的基本使用,含教程和代码
主要介绍了nodejs使用express获取get和post传值及session验证的方法,结合实例形式分析了nodejs使用express实现获取get和post传值及session验证功能的具体操作步骤与注意事项,需要的朋友可以参考下
克隆此存储库git clone https://github.com/gtsopour/nodejs-shopping-cart.git 安装依赖npm install 在启动NodeJS服务器npm start 供Nodemon使用nodemon ./bin/www技术领域NodeJS,Express,Express-Session,...
NULL 博文链接:https://fuyu365-163-com.iteye.com/blog/2154066
上传Nodejs Express 用户登录注册示例,数据库使用mysql,实现用户注册、登录及登录成功跳转到系统界面简单功能
截屏自由思考NodeJS ExpressJS Express-Session EJS Mongoose Mongoodb AngularJS Bootstrap 这个简单的应用程序旨在提供上述技术集成。 NodeJS现在是一个趋势,所以我在这里用它作为服务器ExpressJS 是创建节点 Web...
本篇文章主要介绍了详解nodejs express下使用redis管理session ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
对expres框架的简单封装,支持多进程(cluster模式),支持多进程下session保持,app文件启动非常简单,几行代码而已,一个配置文件搞定
本篇文章主要介绍了node.js中express-session配置项详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Express是一个基于Node.js平台的web应用开发框架,在Node.js基础之上扩展了web应用开发所需要的基础功能,从而使得我们开发Web应用更加方便、更加快捷。 举一个例子: 用node.js实现一个控制台打印“hello server” ...
后端使用 nodejs + express 数据库使用 mongodb 预览 使用 在下载最新的发布版本。 创建.env 配置文件,参考内容如下: DB_HOST=mongodb://localhost:27017/acgnlist JSON_LIMT=1mb URLENCODED_LIMT=1mb JWT_SECRET_...