无法接收来自socket io的redis数据

我使用redis作为python和node之间的pubsub messenger构build实时可视化。 总是有一个python脚本运行,用hmset设置redis散列。 如果我在redis客户端中input以下示例命令:“HGETALL'sellers-80183917'”,那么应用程序的这一边工作正常,我最终得到正确的数据。

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

我用节点运行下面的代码:

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()方法从来没有收到任何东西,我没有看到问题的地方,除了这一切似乎一切正常。

我认为你可能会对Redis中的Pub / Sub实际上是什么感到困惑。 这不是一个听取哈希变化的方法; 你可以有一个叫做sellers-1的Pub / Sub 频道 ,你可以和主要sellers-1一起做一个散列 ,但是这些频道是互不相关的。

如此处所logging:

Pub / Sub与关键空间没有任何关系。

有一种叫做密钥空间的通知 ,可以用来监听密钥空间的变化(通过Pub / Sub通道)。 但是,此function默认情况下不会启用,因为它会占用更多的资源。

也许一个更简单的方法是在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', ... ) 

你显然必须跟踪每个“活跃”的卖家订阅。 要么,要么为每个订阅创build一个新的连接,这也是不理想的。

有一个发布所有更改的发布/订阅渠道可能是一个更好的主意,而不是每个销售者的单独渠道。

最后,如果你的卖家ID不难猜测(例如,如果它是基于一个递增的整数值的话),对于有人写一个客户端来说,这将是微不足道的,喜欢。 这可能不是一个问题,但它需要注意的。