使用Node.js和Redis实现push服务--转载

出处:http://blog.csdn.net/unityoxb/article/details/8532028

push服务是一项很有用处的技术,它能改善交互,提升用户体验。要实现这项服务通常有两种途径,轮询和长连接。轮询就是客户端每隔一段时间就问服务器拿新数据,实现起来很简单但是服务器压力很大,而且大部分请求因为没有新数据都显得很浪费。长连接则是服务器将一个请求挂起,不输出任何内容,直到有新数据产生后才会完成这个请求,浏览器收到响应后则马上再发一个又让服务器挂住,如此反复。这么做的好处是能节省很多无用的请求,但是它不能使用传统的服务端软件,比如apache和php-fpm,客户端多了的话很容易把所有进程占光,这样服务器就没法响应新的请求了。

Node.js让这一切变得简单,它是基于事件和非阻塞I/O的服务器技术,能使用极少的资源响应大量并发的请求,非常适合长连接的要求。但是这样做还存在两个问题。首先你的服务端通常是用另外一套语言和框架做的,有成熟的代码和业务逻辑,为了实现这个push功能,难道又要用javascript来写一套吗?维护起来不嫌麻烦?其次,服务端把请求挂起后,也是不断地重复调用其它服务来获取新数据,这不过是把轮询的代码换个位置而已,本质上没区别,对服务器一样有压力。

有没有什么简单的办法来实现高效的push呢?

答案是有,而且很简单,所需代码不超过20行!

首先我们借助Redis的Pub/Sub功能来实现真正的push,其次用JSON来作为客户端和服务端沟通的数据格式。

当Node.js收到请求后,我们将请求挂起,同时实例化一个Redis客户端,并根据请求里的参数来收听一个特定的频道,原有的服务端代码(比如PHP)处理完业务逻辑后,将新数据用JSON封装下发布到这个频道,Node.js收到消息后将其作为响应传给客户端,这样就完成了一次push。代码如下

[javascript] view plaincopy

  1. var http = require(‘http‘);
  2. var url = require(‘url‘);
  3. var redis = require(‘redis‘);
  4. http.createServer(function (req, res) {
  5. var query = url.parse(req.url, true).query;
  6. if(typeof query.channel == ‘undefined‘){
  7. res.writeHead(200, {‘Content-Type‘: ‘text/plain‘});
  8. res.end(‘Invalid Request\n‘);
  9. }else{
  10. var client = redis.createClient(6379, ‘127.0.0.1‘);
  11. client.subscribe(query.channel);
  12. client.on(‘message‘, function(channel, message){
  13. res.writeHead(200, {‘Content-Type‘: ‘application/json‘});
  14. res.end(message);
  15. client.unsubscribe();
  16. client.end();
  17. });
  18. }
  19. }).listen(1337, ‘127.0.0.1‘);

这个方法简单易用,你只需要定好一个频道和数据关系的协议,然后对现有代码做些简单修改,就能实现一个高效的push服务了!

时间: 2024-08-06 02:02:15

使用Node.js和Redis实现push服务--转载的相关文章

Node.js操作Redis的简单示例

Redis是一个key-value类型的数据库,而key全部都是字符串,value可以是集合.hash.list等等. Redis是通过MULTI/DISCARD/EXEC/WATCH这4个命令来实现事务功能.对事务,我们必须知道事务安全性是一个非常重要的. 事务提供了一种"将多个命令打包,然后一次性.按顺序执行"的机制,并且在事务执行期间不会中断--意思就是在事务完成之前,客户端的其他命令都是阻塞状态. var redis = require("redis");

node.js与redis

最近在学习node创建项目,因为一直在用像mysql这样的结构型数据库,想学点新的东西,所以就把数据库换成了redis.redis是非关系型数据库.那关系型数据库跟非关系型数据库有什么区别呢?简单地说,就是一个有表的概念,一个没有.具体的区别自行Google吧.这里我主要介绍一下node.js与redis之间建立连接的过程,就是说如何早node:里面操作redis'数据库.因此,默认你已经装好这两个软件了. 第一步,我们需要打开redis的服务器.打开命令行,切换到redis安装目录,输入命令:

node.js应用Redis数据库

node.js下使用Redis,首先: 1.有一台安装了Redis的服务器,当然,安装在本机也行 2.本机,也就是客户端,要装node.js 3.项目要安装nodejs_redis模块 注意第 3 点,不是在本机安装就行了,而是说,要在项目中安装(引用). 方法是,DOS窗口,在项目目录下,输入 npm install redis 这样就将nodejs_redis下载一份,放到当前目录下了.看看,多了一个文件夹:node_modules\redis 编写以下代码,保存到当前目录下\hello.j

JavaScript(React Native、Node.js等)移动、服务端通吃的全栈语言

作者:李宁老师 东北大学计算机专业硕士.曾任沈阳东软股份项目经理.51CTO学院签约讲师.从事软件研究和开发超过20年.长久以来一直从事Java.Android.iOS.C++.Swift.Objective-C以及跨平台游戏引擎(Cocos2d-x.Unity3D等)的开发和技术指导工作.对国内外相关领域的技术.理论和实践有很深的理解和研究. 主要著作包括<Cocos2d-x实战游戏开发指南>(即将出版).<Swift权威指南>.<Android深度探索 卷1和卷2>

Node.js调用百度地图Web服务API的Geocoding接口进行点位反地理信息编码

(从我的新浪博客上搬来的,做了一些修改.) 最近迷上了node.js以及JavaScript.现在接到一个活,要解析一个出租车点位数据的地理信息.于是就想到使用Node.js调用百度地图API进行解析. 使用的库主要就是有fs.request. // 请求包 var fs = require('fs');var request = require('request'); // 设置百度API的参数var baiduApiKey = "cQV9U4QhamoOjg6rjdOTAQSiUMxxxxx

node.js中net网络模块TCP服务端与客户端的使用

node.js中net模块为我们提供了TCP服务器和客户端通信的各种接口. 一.创建服务器并监听端口 const net = require('net'); //创建一个tcp服务 //参数一表示创建服务的一些配置 //参数二表示 事件 'connection' 监听回调函数 let server = net.createServer({ //表示是否允许一个半开的TCP连接,默认为false allowHalfOpen: false, //一旦来了连接,是否暂停套接字,默认为false pau

[Node.js]操作redis

摘要 在实际开发中,免不了要操作mysql,mongodb,redis等数据存储服务器.这里先简单介绍如何操作redis. 一个例子 关于redis服务端的安装这里不再介绍,重点不在这里.感兴趣的可以自行安装. 对于一个新的模块,我们需要在我们的项目中先安装redis模块才能用. 命令 cnpm install redis 新建一个redis.js的文件,代码如下: //引入redis var redis = require("redis"); //创建redis客户端 var cli

在 Node.js 上调用 WCF Web 服务

var BasicHttpBinding = require('wcf.js').BasicHttpBinding , Proxy = require('wcf.js').Proxy , binding = new BasicHttpBinding( { SecurityMode: "TransportWithMessageCredential" , MessageClientCredentialType: "UserName" }) , proxy = new P

node.js模拟抄表 tcp服务端和客户端

2015-11-18 09:38:01 服务端 var net = require('net'); var server = net.createServer(function (socket) { socket.on('data', function (data) { console.log(data); // data = JSON.parse(data); console.log('此次需要的类型是:' + data.transType); if (data.order == 'order