奇怪的行为在Redis + Node.js + Socket.io + Django /芹菜设置。 断开连接的套接字仍然收到消息

我面临着一个我自己无法解决的奇怪问题。 我build立了一个设置,通过Django / Celery定期任务发送JSON序列化消息。 此任务通过Redis与node.js服务器进行通信。 Node.js通过使用webbrowser的socket.io来处理通信。

Django /芹菜任务

@periodic_task(run_every=crontab()) # every minute def process_channels(): r = redis.StrictRedis(host='localhost', port=6379, db=0) for i in xrange(1,21): # 1..20 data_dict = {} data_dict['time'] = time.ctime(time.time()) data_dict['message'] = os.urandom(10).encode('hex') r.publish('channel', json.dumps(data_dict) ) time.sleep(2) 

node.js服务器

 var http = require('http'); var server = http.createServer().listen(4000); var io = require('socket.io').listen(server); var querystring = require('querystring') var redis = require('socket.io/node_modules/redis'); var sub = redis.createClient(); sub.subscribe('channel'); io.sockets.on('connection', function (socket) { // grab message from Redis and send to client sub.on('message', function(channel, message) { console.log(message + ' ' + channel + ' ' + socket.id); socket.send(message); }); socket.on('disconnect', function() { console.log('disconnected') }); }); 

的index.html

 $(document).ready( function() { var socket = io.connect('localhost', { port: 4000 }); socket.on('connect', function() { console.log("connecting"); }); socket.on('message', function(message) { // deserialize message from DJANGO var data = JSON.parse(message); //Append message to the bottom of the list $('#comments').append('Time: ' + data.time + '<br />'); $('#comments').append('Message: ' + data.message + '<br /><br />'); } }); }); 

很简单。 该任务通过Redis将随机生成的消息发送到发送到浏览器的节点服务器。 正如你所看到的,我在节点服务器中logging了消息和socket.id。

一切工作如预期,直到我做一个页面重新加载。 当我第一次加载页面时,服务器控制台打印出如下的内容:

 {"message": "85105676e21512a33e72", "time": "Fri Oct 18 22:33:10 2013"} channel 94k39P2j9dMv1JEZRW6Q 

当我重新加载页面时出现:

 disconnected {"message": "c3e93646d60a5a6727f6", "time": "Fri Oct 18 22:33:18 2013"} channel 94k39P2j9dMv1JEZRW6Q {"message": "c3e93646d60a5a6727f6", "time": "Fri Oct 18 22:33:18 2013"} channel wJwsRvpgEks7g1AURW6R 

相同的消息已被发送两次。 每次我重新加载页面消息发送一次。 查看socket.ids(3rd字段),似乎是在重新加载前服务器没有正确断开连接,并且服务器仍然通过该套接字发送消息。 我不明白这个行为。 “断开”方法被调用,所以应该以任何方式处理。 有人可以帮我吗?

提前谢谢了。

在客户端尝试socket.once()而不是socket.on()。

 socket.once('message', function() { ... } 

问题可能是每次重新加载页面时,都会附加多个监听器。 我面临类似的问题,“.once()”是我能find的唯一解决scheme。

如果这没有帮助,你可以尝试探索这里发布的类似问题。 希望它可以帮助:) https://github.com/LearnBoost/socket.io/issues/997