在作商品拍卖的时候,要求在商品的拍卖页面须要实时的更新当前商品的最高价格。实现的方式有不少,好比:php
1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时)html
2. AJAX轮询方式方式推送数据(缺点:服务端须要在死循环中反复查询数据库)html5
3.websocket推送数据(缺点:仅支持html5标准的浏览器)node
socket.io的简要介绍web
全部客户端都经过socket.io挂在nodejs服务器上(注意: 只是挂着,不须要任何循环,由于它是事件驱动的);须要推送消息了,服务器就与nodejs通讯(好比访问某个地址来实现),告诉它推送什么消息到哪里;nodejs收到推送信号后,则经过socket.io实时传输数据给浏览器。这个其实也是一条单向的路,由于nodejs服务器不具有与php通讯的能力,实际上也不须要,网页上直接连php就能够了。redis
接下来开始整理下思路数据库
1.正如简要介绍中所说的首先要将客户端都经过socket.io挂在nodejs服务器上.express
在用户进入拍卖页面后开始链接socket.io ,而后将当前客户端的'用户id','拍卖id','当前最高价','socket.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');
}
});
}