Как можно, чтобы разные веб-браузеры подписывались на отдельные каналы в настройках паба / подузла Redis / Node.js / Socket.io? - PullRequest
3 голосов
/ 11 ноября 2011

Мне бы хотелось, чтобы разные клиенты (веб-браузеры) могли подписываться на отдельные каналы Redis.

Я могу передать запрошенный канал со страницы клиента на сервер node.js. Но если у меня подписано три браузера, каждый подписывается на три отдельных канала, все три браузера получают сообщения, опубликованные на любом из трех каналов.

Вот клиентский HTML-код. У меня есть три отдельные страницы с жестко закодированным названием канала. В этом примере канал является «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>

Вот файл Node.js.

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

1 Ответ

6 голосов
/ 11 ноября 2011

Согласно вашему примеру, приложение откроет новое подключение redis для каждого пользователя, что не имеет смысла.

Это использует одно подключение для всего приложения (вам нужно создать еще одно подключение для публикации данных) для дополнительных заданий

на стороне клиента

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

на стороне сервера

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