如何使用redis PUBLISH / SUBSCRIBE与nodejs在数据值发生变化时通知客户端?

时间:2010-12-14 16:53:16

标签: javascript node.js redis

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

8 个答案:

答案 0 :(得分:122)

OLD仅使用引用

依赖关系

使用expresssocket.ionode_redis,最后但并非最不重要的是来自媒体大火的sample code

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

首先你应该(如果你还没有这样做)安装node.js+npm in 30 seconds(正确的方法,因为你运行npm作为 root ):< / p>

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.

zip内有什么

<强> ./ 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();
        });
    });
}

<强> ./公共/ 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!"

答案 1 :(得分:23)

这是一个没有很多依赖项的简化示例。 您仍然需要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

in redis-cli:

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

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

2013年4月23日其他:我还要注意,当客户端订阅发布/订阅者频道时,它会进入订阅者模式并且仅限于订阅者命令。您只需要创建redis客户端的其他实例。 client1 = redis.createClient(), client2 = redis.createClient()因此可以处于订户模式,另一个可以发出常规数据库命令。

答案 2 :(得分:7)

完成 Redis发布/子示例(实时聊天使用Hapi.js&amp; Socket.io)

我们试图了解Redis发布/订阅(&#34; Pub / Sub &#34;)并且所有现有示例都已过时,过于简单或没有测试。 所以我们使用Hapi.js + Socket.io + Redis Pub / Sub示例编写了一个 完整的实时聊天

  

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

不是在这里粘贴它(没有任何上下文),我们鼓励你签出/尝试示例

我们使用Hapi.js构建了它,但是来自Hapi的chat.js文件解耦并且可以轻松一起使用基本 node.js http服务器快递(等)

答案 3 :(得分:4)

处理redis错误以阻止nodejs退出。你可以写这个;

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

我认为你得到了例外,因为你使用的是订阅发布消息的同一个客户端。创建一个单独的客户端来发布消息,这可以解决您的问题。

答案 4 :(得分:2)

结帐acani-node on GitHub,尤其是文件acani-node-server.js。如果这些链接被破坏,请在acani's GitHub public repositories中查找acani-chat-server。

答案 5 :(得分:2)

如果你想使用socket.io 0.7 AND 一个外部网络服务器你需要改变(除了staticProvider - &gt;静态问题):

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

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

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

答案 6 :(得分:1)

更新代码:

  

staticProvider

现在已重命名为

  

静态

请参阅migration guide

答案 7 :(得分:0)

根据@alex解决方案。如果你有@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