2

自分では解決できない奇妙な問題に直面しています。Django/Celery の定期的なタスクを通じて、JSON シリアル化されたメッセージを送信するセットアップを確立しました。このタスクは、Redis を介して node.js サーバーと通信します。Node.js は、Web ブラウザーとの 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 経由でノード サーバーに送信し、そこからブラウザに送信されます。ご覧のとおり、ノード サーバー内でメッセージと 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

同じメッセージが 2 回送信されました。ページをリロードするたびに、メッセージがもう一度送信されます。socket.ids (3 番目のフィールド) を見ると、リロードする前にソケットが適切に切断されておらず、サーバーがまだそのソケットを介してメッセージを送信しているようです。この振る舞いがわかりません。「切断」メソッドが呼び出されたため、何らかの方法で処理する必要があります。誰かが私を助けることができますか?

よろしくお願いします。

4

1 に答える 1