3

I'd like different clients (web browsers) to be able to subscribe to separate Redis channels.

I'm able to pass the requested channel from the client page to the node.js server. But, if I have three browsers subscribe each subscribe three separate channels, all three browsers receive messages published to any of the three channels.

Here is the client HTML code. I have three separate pages with the channel name hardcoded into it. In this example, the channel is "channel1".

client1.html

<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('giveChannel', function () {
    console.log('sending channel');
    socket.emit('sendChannel', "{\"channel\":\"channel\"}");
});

socket.on('message', function (data) {
    console.log(data);
});
</script>

Here is the Node.js file.

app.js

redis = require('redis'),
sys = require('sys');
var http = require('http');
var url = require('url');
var fs = require('fs');

var server = http.createServer(function (req, res) {
    var path = url.parse(req.url).pathname;
    fs.readFile(__dirname + path, function(err, data) {
        if (err) return null;
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(data, 'utf8');
        res.end();
    });

});

io = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
    var rc = redis.createClient();

    rc.on("connect", function() {
        sys.log('connected to redis');
    });

    rc.on("message", function (channel, message) {
        sys.log("Sending: " + message);
        io.sockets.emit('message', message);
    });

    socket.emit('giveChannel');
    socket.on('sendChannel', function (msg) {
        console.log(msg);
        var data = JSON.parse(msg);
        console.log(data.channel);
        rc.subscribe(data.channel);
    });
});

server.listen(8000, '0.0.0.0');
Nick Messick
  • 3,202
  • 3
  • 30
  • 41

1 Answers1

6

As per your example APP will open a new redis connection per every user,that doesn't make sense.

This use one connection for entire app (you have to make one more connection for publish the data) for sub jobs

Client Side

    var socket = io.connect('http://localhost:3000');

socket.emit('channel','US');
socket.on('news',function(news){
    $("body").append('<br/>' + news);
});

socket.on('message',function(msg){
    $("body").append('<br/>' + msg);
});

Server Side

var io      = require('socket.io');
var express = require('express');
var app     = express.createServer();

io = io.listen(app);

app.listen('3000');
var pub = require('node_redis').createClient(); //publish cli
var redis = require('node_redis').createClient(); //sub cli
redis.psubscribe('*');  

redis.on('pmessage',function(pat,ch,msg){
    io.sockets.in(ch).emit('news',msg);
});

io.sockets.on('connection',function(socket){
    console.log('Socket connected: ' + socket.id);

    socket.on('channel',function(ch){
        socket.join(ch)

         //Publishing data on ch
         pub.publish(ch,"Hello " + ch);  
    });


    socket.on('disconnect',function(){
        console.log('Socket dis connected: ' + socket.id);
    });
});


console.log('Server started @ 3000');
Ganesh Kumar
  • 1,341
  • 11
  • 18