在做商品拍卖的时候,要求在商品的拍卖页面需要实时的更新当前商品的最高价格。实现的方式有很多,比如:

1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时)

2. AJAX轮询方式方式推送数据(缺点:服务端需要在死循环中反复查询数据库)

3.websocket推送数据(缺点:仅支持html5标准的浏览器)

socket.io的简要介绍

所有客户端都通过socket.io挂在nodejs服务器上(注意: 只是挂着,不需要任何循环,因为它是事件驱动的);需要推送消息了,服务器就与nodejs通信(比如访问某个地址来实现),告诉它推送什么消息到哪里;nodejs收到推送信号后,则通过socket.io实时传输数据给浏览器。这个其实也是一条单向的路,因为nodejs服务器不具备与php通信的能力,实际上也不需要,网页上直接连php就可以了。

接下来开始整理下思路

1.正如简要介绍中所说的首先要将客户端都通过socket.io挂在nodejs服务器上.

在用户进入拍卖页面后开始连接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');

}

});

}

用node.js(socket.io)实现数据实时推送的更多相关文章

  1. 使用Node.js+Socket.IO搭建WebSocket实时应用

    Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...

  2. (转)使用Node.js+Socket.IO搭建WebSocket实时应用

    Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...

  3. 使用Node.js+Socket.IO搭建WebSocket实时应用【转载】

    原文:http://www.jianshu.com/p/d9b1273a93fd Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新 ...

  4. 利用socket.io实现消息实时推送

    最近在写的项目中存在着社交模块,需要实现这样的一个功能:当发生了用户被点赞.评论.关注等操作时,需要由服务器向用户实时地推送一条消息.最终完成的项目地址为:socket-message-push,这里 ...

  5. 转载:node.js socket.io

    本文转自:http://www.xiaocai.name/post/cf1f9_7b6507  学习node.js socket.io 使用 用node.js(socket.io)实现数据实时推送 在 ...

  6. 基于node.js+socket.io+html5实现的斗地主游戏(1)概述

    一.游戏描述 说是斗地主游戏,其实是寝室自创的"捉双A",跟很多地方的捉红10.打红A差不多,大概规则是: 1.基础牌型和斗地主一样,但没有大小王,共52张牌,每人13张,这也是为 ...

  7. WebSocket和kafka实现数据实时推送到前端

    一. 需求背景      最近新接触一个需求,需要将kafka中的数据实时推送到前端展示.最开始想到的是前端轮询接口数据,但是无法保证轮询的频率和消费的频率完全一致,或造成数据缺失等问题.最终确定用利 ...

  8. node.js+socket.io配置详解

    由于我是在win7的环境下,在这里就以win7系统为例进行讲解了. 首先需要在nodejs官网下载最新版的node.js,下载完毕直接安装即可,安装成功后在cmd命令行中执行node指令,如下结果就说 ...

  9. 使用node.js + socket.io + redis实现基本的聊天室场景

    在这篇文章Redis数据库及其基本操作中介绍了Redis及redis-cli的基本操作. 其中的publish-subscribe机制应用比较广泛, 那么接下来使用nodejs来实现该机制. 本文是对 ...

随机推荐

  1. tcl/tk 调用选择路径的窗口

    tk_chooseDirectory -title "选择工作空间" -initialdir "D:\\" -title 指定打开后显示的title -init ...

  2. JSON.parse(JSON.stringify()) 实现对对象的深度拷贝,从而互不影响

    JSON.parse(JSON.stringify({"key": "value"})) 根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字 ...

  3. DELPHI +ClientDataSet+DBGRIDEH 进行排序

    DELPHI +ClientDataSet+DBGRIDEH  进行排序因为使用了DBX+ClientDataSet,所以排序显得简单些,只需要设定几个属性就OK了.1.DbGridEH 中设定:Op ...

  4. PBS 作业调度应用

    PBS(Portable Batch System),最初由 NASA 的 Ames 研究中心开发,主要为了提供一个能满足异构计算网络需要的软件包,用于灵活的批处理(Portable Batch Pr ...

  5. 简明Python3教程 7.运算符和表达式

    简介 你写的大多数逻辑行都包含表达式.表达式的一个简单例子是2 + 3.一个表达式可分为操作符和操作数两部分. 操作符的功能是执行一项任务:操作符可由一个符号或关键字代表,如+ .操作符需要数据以供执 ...

  6. C. Adidas vs Adivon

    C. Adidas vs Adivon Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer ...

  7. Monthly Expense

    Problem Description Farmer John is an astounding accounting wizard and has realized he might run out ...

  8. Proxy Design Pattern 代理设计模式

    代理设计模式.此模式是用于serverclient排序.互联网接入,也经常使用的类代理,我觉得这种感觉很复杂.但是,这种设计模式本身是非常easy的. 是一类调用另一个类的功能.客户调用类,实际工作是 ...

  9. OpenGL(十二) 纹理映射(贴图)

    OpenGL绘制纹理的步骤: 1. 开启纹理功能 使用glEnable(GL_TEXTURE_2D)开启2D纹理功能,使用glDisable(GL_TEXTURE_2D)关闭纹理,默认情况下纹理是关闭 ...

  10. 网络库Asio交叉编译(Linux生成ARM)

    1.  Asio是一个跨平台的C++库,用于网络和底层I/O编程.Asio使用先进的C++方式提供了一系列的异步模型 2. 官方网址:http://think-async.com 3. 由于Asio库 ...