如何让不同的 Web 浏览器订阅 Redis/Node.js/Socket.io pub/sub 设置中的单独频道?

发布于 2024-12-14 13:56:25 字数 1738 浏览 2 评论 0原文

我希望不同的客户端(网络浏览器)能够订阅单独的 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');

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拧巴小姐 2024-12-21 13:56:25

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

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');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文