如何使用redis的PUBLISH / SUBSCRIBE和nodejs在数据值改变时通知客户端?

我正在用NodeJS和Redis编写一个事件驱动的发布/订阅应用程序。 我需要一个如何在Redis中的数据值发生变化时通知Web客户端的示例。

旧的只使用一个引用

依赖

使用express , socket.io , node_redis ,最后但并非最不重要的代码来自媒体火灾。

安装node.js + npm(非root用户)

首先你应该(如果你还没有这样做) 在30秒内安装node.js + npm (正确的方法,因为你不应该以root身份运行npm):

echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc . ~/.bashrc mkdir ~/local mkdir ~/node-latest-install cd ~/node-latest-install curl http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1 ./configure --prefix=~/local make install # ok, fine, this step probably takes more than 30 seconds... curl http://npmjs.org/install.sh | sh 

安装依赖关系

在安装node + npm之后,您应该通过发出以下命令来安装依赖关系:

 npm install express npm install socket.io npm install hiredis redis # hiredis to use c binding for redis => FAST :) 

下载示例

你可以从mediafire下载完整的样本。

解压缩包

 unzip pbsb.zip # can also do via graphical interface if you prefer. 

什么是拉链

./app.js

 const PORT = 3000; const HOST = 'localhost'; var express = require('express'); var app = module.exports = express.createServer(); app.use(express.staticProvider(__dirname + '/public')); const redis = require('redis'); const client = redis.createClient(); const io = require('socket.io'); if (!module.parent) { app.listen(PORT, HOST); console.log("Express server listening on port %d", app.address().port) const socket = io.listen(app); socket.on('connection', function(client) { const subscribe = redis.createClient(); subscribe.subscribe('pubsub'); // listen to messages from channel pubsub subscribe.on("message", function(channel, message) { client.send(message); }); client.on('message', function(msg) { }); client.on('disconnect', function() { subscribe.quit(); }); }); } 

./public/index.html

 <html> <head> <title>PubSub</title> <script src="/socket.io/socket.io.js"></script> <script src="/javascripts/jquery-1.4.3.min.js"></script> </head> <body> <div id="content"></div> <script> $(document).ready(function() { var socket = new io.Socket('localhost', {port: 3000, rememberTransport: false/*, transports: ['xhr-polling']*/}); var content = $('#content'); socket.on('connect', function() { }); socket.on('message', function(message){ content.prepend(message + '<br />'); }) ; socket.on('disconnect', function() { console.log('disconnected'); content.html("<b>Disconnected!</b>"); }); socket.connect(); }); </script> </body> </html> 

启动服务器

 cd pbsb node app.js 

启动浏览器

最好,如果你开始谷歌浏览器(由于websockets的支持,但不是必要的)。 访问http://localhost:3000来查看示例(一开始除PubSub没有其他任何内容)。

但在publish到频道pubsub您应该看到一条消息。 下面我们发布"Hello world!" 到浏览器。

来自./redis-cli

 publish pubsub "Hello world!" 

这里有一个简单的例子,没有太多的依赖关系。 你仍然需要npm install hiredis redis

节点JavaScript:

 var redis = require("redis"), client = redis.createClient(); client.subscribe("pubsub"); client.on("message", function(channel, message){ console.log(channel + ": " + message); }); 

…把它放在pubsub.js文件中,运行node pubsub.js

在redis-cli中:

 redis> publish pubsub "Hello Wonky!" (integer) 1 

应该显示: pubsub: Hello Wonky! 在terminal运行节点! 恭喜!

附加2013年4月23日:我还想指出,当一个客户端订阅一个发布/订阅渠道时,它进入订户模式,仅限于订户命令。 你只需要创build额外的redis客户端实例。 client1 = redis.createClient(), client2 = redis.createClient()所以可以处于用户模式,另一个可以发出常规的DB命令。

完成 Redis Pub / Sub示例(使用Hapi.js和Socket.io 进行实时聊天

我们试图了解Redis的发布/订阅(“ Pub / Sub ”),所有现有的例子都已经过时,太简单或者没有testing。 因此,我们使用Hapi.js + Socket.io + Redis Pub / Sub示例进行完整的实时聊天,并进行了端到端testing

https://github.com/dwyl/hapi-socketio- redis-chat-example

构建状态 测试覆盖率 守则气候 依赖状态 devDependency状态

Pub / Sub组件只有几行node.js代码: https : //github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40

我们build议您结帐/尝试示例,而不是在此粘贴( 没有任何上下文 )。

我们使用Hapi.js来构build它,但是chat.js文件是从Hapi中分离出来的,并且可以很容易地用于基本的 node.js http服务器express (等等)

处理redis错误以阻止nodejs退出。 你可以通过写作来做到这一点。

 subcribe.on("error", function(){ //Deal with error }) 

我想你会得到这个exception,因为你正在使用订阅发布消息的同一个客户端。 创build一个单独的客户端发布消息,并可以解决您的问题。

查看GitHub上的acani-node ,尤其是文件acani-node-server.js 。 如果这些链接被破坏,请在acani的GitHub公共存储库中查找acani-chat-server。

如果你想得到这个与socket.io 0.7 外部networking服务器的工作,你需要改变(除了staticProvider – >静态问题):

a)在index.html中提供域名而不是localhost(即var socket = io.connect('http://my.domain.com:3000');;)

b)在app.js中更改HOST(即const HOST ='my.domain.com';)

c)并在app.js的第37行添加套接字 (即'socket.sockets.on('connection',function(client){…')

更新到代码:

staticProvider

现在改名为

静态的

请参阅迁移指南

根据@alex解决scheme。 如果你有这样一个错误,像每个@tyler提及:

 node.js:134 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: Redis connection to 127.0.0.1:6379 failed - ECONNREFUSED, Connection refused at Socket. 

那么你需要先安装Redis 。 看一下这个:

http://redis.io/download