无法从套接字i

时间:2016-09-27 19:50:58

标签: node.js redis socket.io

我使用redis作为python和node之间的pubsub messenger构建实时可视化。总是运行一个python脚本,它使用hmset设置redis哈希。如果我输入以下示例命令,应用程序的这一侧工作正常:" HGETALL' sellers-80183917'"在redis客户端,我最终获得了正确的数据。

问题出在js方面。我使用socketio和redis nodejs库来监听redis实例并通过d3js在线发布结果。

我使用node运行以下代码:

var express = require('express');
var app = express();
var redis = require('redis');

app.use(express.static(__dirname + '/public'));


var http = require('http').Server(app);


var io = require('socket.io')(http);
var sredis = require('socket.io-redis');
io.adapter(sredis({ host: 'localhost', port: 6379 }));



redisSubscriber = redis.createClient(6379, 'localhost', {});


redisSubscriber.on('message', function(channel, message) {
  io.emit(channel, message);
});



app.get('/sellers/:seller_id', function(req, res){
  var seller_id = req.params.seller_id;
  redisSubscriber.subscribe('sellers-'.concat(seller_id)); 


  res.render( 'seller.ejs', { seller:seller_id } );
});


http.listen(3000, '127.0.0.1', function(){
  console.log('listening on *:3000');
});

这是seller.ejs文件的相关部分,它接收用户请求并输出即:

        var socket = io('http://localhost:3000');
        var stats;
        var seller_key = 'sellers-'.concat(<%= seller %>);
        socket.on(seller_key, function(msg){
            stats = [];
            console.log('Im in');
            var seller = $.parseJSON(msg);
            var items = seller['items'];
            for(item in items) {
                var item_data = items[item];
                stats.push({'title': item_data['title'], 'today_visits': item_data['today_visits'], 'sold_today': item_data['sold_today'], 'conversion_rate': item_data['conversion_rate']});
            }
            setupData(stats);
        });

问题是socket_on()方法永远不会收到任何东西,我不知道问题出在哪里,因为除此之外一切似乎都运行正常。

1 个答案:

答案 0 :(得分:1)

我认为你可能会对Redis中的Pub / Sub实际上是什么感到困惑。它是一种倾听哈希变化的方法;您可以使用名为sellers-1的发布/订阅频道,并且您可以使用密钥sellers-1创建哈希,但这些哈希与每个密钥相关联其他

记录在案here

  

Pub / Sub与密钥空间无关。

有一个名为keyspace notifications的东西,可以用来收听密钥空间的变化(通过Pub / Sub通道);但是,默认情况下,此功能未启用,因为它会占用更多资源。

也许更容易的方法是在HMSET之后发布消息,因此任何订阅者都会知道哈希值已经改变(他们会自己检索哈希内容,或者发布的消息将包含相关数据) )。

这将我们带到下一个可能的问题:您只有一个订阅者连接redisSubscriber

根据我从Node.js Redis驱动程序的理解,在这样的连接上调用.subscribe()将删除任何先前的订阅,而不是新的订阅。因此,如果您之前订阅了sellers-1频道并订阅了sellers-2,那么您将无法再从sellers-1频道接收消息。

您可以通过传递一个通道数组或通过将它们作为参数传递来侦听多个通道:

redisSubscriber.subscribe([ 'sellers-1', 'sellers-2', ... ])
// Or:
redisSubscriber.subscribe('sellers-1', 'sellers-2', ... )

你显然必须跟踪每个&#34;活跃的&#34;卖家订阅。要么是这样,要么为每个订阅创建一个新的连接,这也不是理想的。

拥有一个发布所有更改的单个发布/订阅频道可能更好一点,而不是每个卖家都有单独的频道。

最后:如果您的卖家ID难以猜测(例如,如果它基于增量整数值),那么有人写一个客户端是很容易的可以收听他们喜欢的任何卖家渠道。这可能不是问题,但要注意的事情。