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.
8 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!"

- 60,935
- 33
- 147
- 186
-
why do you need `const client = redis.createClient()` in the root of app.js? – Akasha Apr 14 '12 at 18:40
-
you don't need to use const at all. var could be used as well and maybe I should have instead because const is only available in the newer javascript engines. Furthermore this line ensures we are connected to redis server which we use in this example. – Alfred Apr 14 '12 at 22:05
-
@Alfred I tried your example and it seems that it never goes in the socket.on('connection', function(client) { block. I tried to print something there and never does. if I remove this part I can normally publish and see the message in the console. Also when I run pubsub.js the following are printed on the console: Express server listening on port3000 info - socket.io started Do you maybe have an idea of what might be wrong in my case? – x_maras Jun 12 '12 at 12:06
-
5The sample is very old so not up to date with latest socket.io/express modules and maybe even node.js. I would try to update code. There is also another huge problem with this code that it opens another redis connection for each connected user. That should only be on instead. I have to work first, but after that I try to update the code. – Alfred Jun 12 '12 at 16:00
-
@Alfred I think that I managed to fixed it. Not sure if my code is good (it's my second day that I work with node.js). I 've put it on github(I wanted to play a little bit with it as well) https://github.com/dinostheo/redis_pbsb_node.js_socket.io_Hello_world – x_maras Jun 13 '12 at 13:28
-
1Very good. I still think there is room for some improvements which when I have time I will put online. But right now I am really working hard :$. – Alfred Jun 14 '12 at 03:08
-
@Imme22009 Sorry but I haven't done anything on this since then https://github.com/dinostheo/redis_node_pbsb – x_maras Mar 27 '13 at 10:11
-
1I think subscribe.on should be outside the socket.on('connection') block to avoid multiple subscribes/ – zubinmehta Jul 03 '15 at 09:37
-
Why did you emphasize not to install npm as root? – Phantom007 Aug 31 '18 at 17:08
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.

- 3,077
- 3
- 27
- 35
-
Here when we add data to the redis, should I run publish pubsub to get notification of insert? – IshaS Jul 07 '15 at 10:09
-
1@IshaS if that's what you need to do, yes. You should also look into transactions if you need to run multiple commands atomically: http://redis.io/commands/exec – nak Jul 07 '15 at 13:27
-
@nak This worked like charm in one GO :) Some users may need to install 'double-ended-queue' if not installed already. – Manjeet Jul 22 '17 at 18:53
-
1It also worth to mention that if you want to use wildcards, for example, subscribe to `pubsub/*` just add `p` to the example: replace `subscibe` with `psubscribe` and `message` with `pmessage`. – Liosha Bakoushin Feb 12 '20 at 13:35
Complete Redis Pub/Sub Example (Real-time Chat using Hapi.js & Socket.io)
We were trying to understand Redis Publish/Subscribe ("Pub/Sub") and all the existing examples were either outdated, too simple or had no tests. So we wrote a Complete Real-time Chat using Hapi.js + Socket.io + Redis Pub/Sub Example with End-to-End Tests!
The Pub/Sub component is only a few lines of node.js code: https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40
Rather than pasting it here (without any context) we encourage you to checkout/try the example.
We built it using Hapi.js but the chat.js
file is de-coupled from Hapi and can easily be used with a basic node.js http server or express (etc.)

- 31,111
- 21
- 89
- 120
-
-
@Gixty we wrote the example using Hapi.js *because* all the other examples out there use Express.js ... as mentioned in the post, its trivial to port it to any other Node.js framework (simply pass in the express app/listener to the chat.js init code) and it works exactly the same. p.s: if you are new to Hapi.js see: https://github.com/nelsonic/learn-hapi – nelsonic Jul 28 '15 at 05:53
Handle redis errors to stop nodejs from exiting. You can do this by writing;
subcribe.on("error", function(){
//Deal with error
})
I think you get the exception because you are using the same client which is subscribed to publish messages. Create a separate client for publishing messages and that could solve your problem.

- 875
- 1
- 12
- 25
Check out acani-node on GitHub, especially the file acani-node-server.js. If these links are broken, look for acani-chat-server among acani's GitHub public repositories.

- 121,420
- 116
- 450
- 651
If you want to get this working with socket.io 0.7 AND an external webserver you need to change (besides the staticProvider -> static issue):
a) provide the domain name instead of localhost (i.e. var socket = io.connect('http://my.domain.com:3000'); ) in the index.html
b) change HOST in app.js (i.e. const HOST = 'my.domain.com'; )
c) and add sockets in line 37 of app.js (i.e. 'socket.sockets.on('connection', function(client) { …' )

- 2,460
- 28
- 34
according to @alex solution. if you have an error like this one as per @tyler mention:
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.
then you need to install Redis first. check this out: