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で.
//クライアント
//サービス側
現在のオークションの最高値を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');
}
});
}
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');
}
});
}