今天终于使用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还是不错的。
相关推荐
3. **中间件**:可以使用Express的中间件来验证用户是否已登录,例如在需要登录状态才能访问的路由前添加检查用户session或cookie的中间件。 4. **模板引擎**:如果需要提供用户界面,可以使用Express支持的模板...
基于nodejs+mysql实现的仿京东商城...Cookie-Parser、Cookie-Session进行cookie与session的处理 首页数据的展示 分类页数据的展示 购物车 我的 注册 登录 商品详情页 商品搜索 mysql数据库的安装 运行详情见包内文档
通过这个项目,你可以学习到如何用Node.js和Express搭建服务器,如何使用MongoDB进行数据存储,以及如何实现前后端交互。同时,EJS模板引擎的应用让你了解了服务器端渲染的基本流程。在实际操作中,你还将接触到错误...
使用NodeJs的express框架完成电影网站后端搭建; 使用mongodb完成数据存储,通过mongoose模块完成对mongodb数据的构建; 使用jade模板引擎完成页面创建渲染; 使用Moment.js格式化电影存储时间; 3、本地开发环境...
2. **中间件**:使用Express中间件处理请求、响应,如session管理、错误处理等。 3. **模板引擎**:可能结合Pug或EJS等模板引擎来渲染动态HTML页面。 4. **API设计**:创建RESTful API接口,定义GET、POST、PUT、...
它允许你在MongoDB中持久化Express的session数据,确保用户状态在多个请求间保持一致。 接下来,我们将详细探讨这些技术的使用方法: 1. **Node.js**: 在Node.js环境中,首先需要安装项目所需的依赖包,如`express...
5. **Express框架**:虽然未在描述中提及,但通常在NodeJS后端开发中,我们会使用Express框架来简化HTTP路由和中间件的管理。Express为创建Web应用提供了一个轻量级而灵活的基础。 6. **MySQL**:MySQL是一个流行的...
LazyLoad进行图片赖加载服務端架構使用NodeJs进行后台开发Express中间件进行服务的配置,路由、请求的处理官网http://www.expressjs.com.cn/Mysql中间件处理与数据库的“通信”Body-Parser中间件进行接口请求参数的...
Node.js和Express4提供了基础的Session和Cookie管理,可以实现用户登录状态的保持。同时,为了保护用户数据的安全,我们需要对敏感信息如密码进行加密存储,通常采用bcrypt或argon2算法。 另外,系统的性能优化也是...
一个简单的NodeJS + 网站都已设置好,并准备使用和进行用户名+密码身份验证,使用持久性本地cookie,通过和View模板的和持久性会话使用 。 概述 该站点包括需要身份验证的登录页面,注册页面和索引页面,并且使用...
可以使用JWT(Json Web Tokens)或者Session + Cookie的方式实现。 8. **模板引擎**: 在Express中,我们可以选择EJS、Pug等模板引擎来渲染HTML页面。模板引擎允许将数据和结构分开,方便后端数据与前端展示的结合。...
在本项目中,“nodejs+mysql+ejs完成的博客”是一个使用Node.js后端框架、MySQL数据库和EJS模板引擎构建的全功能博客系统。这个系统涵盖了用户管理、内容展示、交互等多个核心功能,让我们来深入探讨这些技术的运用...
通过理解和实践这个基础模板,开发者可以掌握Node.js的服务器端编程,理解Express框架的使用,并学会如何组织一个简单的Web项目。此外,这个项目还可能包含对错误处理、日志记录、session管理等进阶话题的示例,这些...
总的来说,"NodeJS入门项目案例(Express+Mysql)"是一个很好的起点,它涵盖了Node.js服务端开发的基础知识,包括Express框架的使用和Mysql数据库的集成。通过这个项目,你不仅可以学习到基本的Web应用开发技术,还...
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它允许开发者使用 JavaScript 进行服务器端编程,而 MongoDB 是一个流行的开源、非关系型数据库,特别适合处理大量结构灵活的数据。 **Node.js 知识点:...
2. Node.js的Express框架用于构建RESTful API。 3. MongoDB的基本操作,如CRUD(创建、读取、更新、删除)以及Mongoose库用于与Node.js交互。 4. JSON Web Tokens(JWT)或Session管理用户认证。 5. 前后端通信的...
总之,"nodejs_express_module" 旨在帮助开发者在遇到网络障碍时,仍能顺利部署和使用 Express 框架,从而实现快速构建 Node.js 后端服务。通过理解并熟练运用 Express,你可以创建功能强大的 web 应用,满足各种...
NodeJS之ExpressSession的基本使用,含教程和代码
在Express中,可以使用如`express-session`和`connect-redis`这样的中间件组合,实现session的持久化存储和跨进程访问。 **配置文件管理:** 项目中提到应用启动仅需一个配置文件,这通常意味着项目使用了一种配置...