如何使用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
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 。 看一下这个: