How can I have different web browsers subscribe to separate channels in a Redis/Node.js/Soc…

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

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);
});

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');

Problem courtesy of: messick

Solution

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('
' + news); }); socket.on('message',function(msg){ $("body").append('
' + 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');

Solution courtesy of: Ganesh Kumar

稿源:Node.js Recipes - The solution to all Node problems (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » How can I have different web browsers subscribe to separate channels in a Redis/Node.js/Soc…

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录