nodeでjs(socket.io)はデータのリアルタイムプッシュを実現する

4321 ワード

商品オークションを行う際には、商品のオークションページで現在の商品の最高価格をリアルタイムで更新する必要がある.次のような方法で実現できます.
1.setInterval n秒ごとに非同期でデータを引き出す(欠点:更新がリアルタイムではない)
2.AJAXポーリング方式方式でデータをプッシュする(欠点:サービス側はデッドサイクルでデータベースを繰り返し照会する必要がある)
3.websocketプッシュデータ(欠点:html 5標準のブラウザのみをサポート)
socket.ioの簡単な紹介
すべてのクライアントはsocket.を通過します.ioはnodejsサーバに掛けられています(注意:掛けられているだけで、イベント駆動であるため、ループは必要ありません).メッセージをプッシュする必要がある場合、サーバはnodejsと通信し(例えば、あるアドレスにアクセスして実現する)、どのメッセージをどこにプッシュするかを教えます.Nodejsはプッシュ信号を受信とsocket.ioはブラウザにリアルタイムでデータを転送します.これは、nodejsサーバがphpと通信する能力を備えていないため、実際には必要ありません.ホームページにphpを直接接続すればいいのです.
 
次に考えを整理します
1.簡単な説明で述べたように、まずクライアントをsocket.を通過する.ioはnodejsサーバに掛ける.
ユーザがオークションページに入る後にsocket.への接続を開始する.ioは、現在のクライアントの「ユーザーid」、「オークションid」、「現在最高価格」、「ocket.id′はnodeに格納.jsグローバル変数socketUserで.
//クライアント
var socket = io.connect("http://demo.xiaocai.name":339");

socket.on('conn', function (data) {

  var postdata = {

'c_id'   : PageValue.charinfo.c_id,     //  id

        'c_name' : PageValue.charinfo.c_name,   //    

        'guid'   : PageValue.infodata.id,//  id

        'price'  : PageValue.infodata.max_price,//     

  }

  socket.emit('login', postdata,function(result){

     console.log('    ');

  });

});

//サービス側
var   sio     = require('socket.io');

var   express = require('express');

var   app  =  module.export = express.createServer();

//   

var socketUser = {};

io  = sio.listen(app);

io.set('log level', 1);// socket.io  debug    

//    

io.sockets.on('connection', function (socket){

    //    

    io.sockets.emit('conn', { text: 'socketId:'+socket.id});

    //         socket

    socket.on('login', function (data,fn) {

socketUser[socket.id] = {'c_id':data.c_id,'guid':data.guid,'price':data.price,'socket':socket};

    });

   //    

    socket.on('disconnect', function(){

        console.log('-    ['+socket.id+']-');

        delete socketUser[socket.id];

    });

});

 
現在のオークションの最高値をredisキャッシュから読み出す、そのオークションの下のsocketUserの集合を巡り、その価格が取り出す最高値を下回ると最新の価格をプッシュする(そしてその最高値を更新).GetRedisKeyはreidsを読み取る方法であり、この方法は底部に貼る出す.
    var pushprice = function(guid){
        console.log('-プッシュデータ['+guid+']-');
        common_func.GetRedisKey("AuctionMaxPrice-"+guid,function(val){
            if(!val){
                return false;
            }
            for(var values in socketUser){
                if(  parseFloat(socketUser[values].price) < val && socketUser[values].guid == guid ){
                    socketUser[values].socket.emit('receive',{'nowprice':val});
                    socketUser[values].price = val;
                }
            }
        });
    }
3.クライアントがプッシュを受けるデータ
socket.on('receive',function(maxprice){
    $('#NowUserTxt').html('¥'+maxprice);
});
 
GetRedisKeyは共通関数でredisキャッシュを取得する方法で、こちらは単独で貼り付けます
exports.GetRedisKey = function(key,fun){
    if( typeof redis_client == 'undefined' ){
        var redis      = require("redis");
        redis_client   = redis.createClient(RedisPort,RedisHost);
        redis_client.on("error", function (err) {
            common_func.insertlog("Error(redis): "+ err);
        })
    }
    redis_client.get(key, function (err, reply) {
        if(reply){
            fun(reply.toString());
        }else{
            fun(false);
            common_func.insertlog('Error(redis): get('+key+') not data');
        }
    });
}