Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use redis PUBLISH/SUBSCRIBE with nodejs to notify clients when data values change?

I'm writing an event-driven publish/subscribe application with NodeJS and Redis. I need an example of how to notify web clients when the data values in Redis change.

like image 423
guilin 桂林 Avatar asked Dec 14 '10 16:12

guilin 桂林


People also ask

How do I implement a pub sub in node JS?

Implementing publish in Node. js file in the publish directory that will contain our code: const redis = require('redis'); const publisher = redis. createClient(); (async () => { const article = { id: '123456', name: 'Using Redis Pub/Sub with Node. js', blog: 'Logrocket Blog', }; await publisher.

How does redis integrate with node js?

Create new session. js file in the root directory with the following content: const express = require('express'); const session = require('express-session'); const redis = require('redis'); const client = redis. createClient(); const redisStore = require('connect-redis')(session); const app = express(); app.

Does redis guarantee message delivery?

Redis does not provide guaranteed delivery using its Pub/Sub mechanism. Moreover, if a subscriber is not actively listening on a channel, it will not receive messages that would have been published.


2 Answers

OLD only use a reference

Dependencies

uses express, socket.io, node_redis and last but not least the sample code from media fire.

Install node.js+npm(as non root)

First you should(if you have not done this yet) install node.js+npm in 30 seconds (the right way because you should NOT run npm as root):

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 

Install dependencies

After you installed node+npm you should install dependencies by issuing:

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

Download sample

You can download complete sample from mediafire.

Unzip package

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

What's inside 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();         });     }); } 

./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> 

Start server

cd pbsb     node app.js 

Start browser

Best if you start google chrome(because of websockets support, but not necessary). Visit http://localhost:3000 to see sample(in the beginning you don't see anything but PubSub as title).

But on publish to channel pubsub you should see a message. Below we publish "Hello world!" to the browser.

From ./redis-cli

publish pubsub "Hello world!" 
like image 74
Alfred Avatar answered Sep 22 '22 20:09

Alfred


here's a simplified example without as many dependencies. You do still need to npm install hiredis redis

The node JavaScript:

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

...put that in a pubsub.js file and run node pubsub.js

in redis-cli:

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

which should display: pubsub: Hello Wonky! in the terminal running node! Congrats!

Additional 4/23/2013: I also want to make note that when a client subscribes to a pub/sub channel it goes into subscriber mode and is limited to subscriber commands. You'll just need to create additional instances of redis clients. client1 = redis.createClient(), client2 = redis.createClient() so one can be in subscriber mode and the other can issue regular DB commands.

like image 38
nak Avatar answered Sep 19 '22 20:09

nak