javascript - 如何让不同的 Web 浏览器订阅 Redis/Node.js/Socket.io 发布/订阅设置中的单独 channel ?

标签 javascript node.js redis socket.io publish-subscribe

我希望不同的客户端(网络浏览器)能够订阅单独的 Redis channel 。

我能够将请求的 channel 从客户端页面传递到 node.js 服务器。但是,如果我有三个浏览器订阅,每个浏览器订阅三个独立的 channel ,所有三个浏览器都会收到发布到三个 channel 中的任何一个的消息。

这是客户端 HTML 代码。我有三个单独的页面, channel 名称硬编码到其中。在这个例子中, channel 是“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');

最佳答案

根据您的示例,APP 将为每个用户打开一个新的 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');

关于javascript - 如何让不同的 Web 浏览器订阅 Redis/Node.js/Socket.io 发布/订阅设置中的单独 channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8089725/

相关文章:

javascript - 为什么我不能在具有 'contenteditable' 属性的 HTML 按钮的文本中添加空格?

javascript - 使用对象作为查找表: Values dont update after first call

c# - 在 StackService.Redis 客户端方法 Store() 上导致 stackoverflow 的递归对象

javascript - 如何更新谷歌标记的位置

javascript - 为什么 mozilla firefox 会记录来自 socket.io 1.2.1 的许多消息

javascript - JS 仅适用于相关项目的条件

java - 在 Virtual Box 上为 Spring Boot 应用程序运行 WAR 时出错

node.js - 使用 Node.js 创建支持 JavaScript 的网络爬虫

node.js - 为什么在单独的模型文件中使用 model.export?

python - 具有 azure Web 应用程序和存储的 Django channel