【问题标题】:realtime visitors with nodejs & redis & socket.io & php使用 nodejs & redis & socket.io & php 的实时访问者
【发布时间】:2013-06-22 21:31:12
【问题描述】:

我是这些技术的新手。

我想为我的网站的每个产品获得实时访问者。 我的意思是像“X 个用户看到这个产品”这样的通知。

每当用户连接到产品时,该产品的计数器就会增加,而当用户断开连接时,该产品的计数器就会减少。

我试图搜索很多文档,但我很困惑。

我正在使用 PHP 的 Predis 库。

我所做的可能完全是错误的。 我不确定在哪里放置 createClient ,何时订阅和何时取消订阅。

我已经做了什么:

在产品详情页面上:

$key = "product_views_".$product_id;
$counter = $redis->incr($key);


$redis->publish("productCounter", json_encode(array("product_id"=> "1000", "counter"=> $counter )));

在 app.js 中

var app = require('express')()
, server = require('http').createServer(app)
, socket = require('socket.io').listen(server,{ log: false })
, url = require('url')
, http= require('http')
, qs = require('querystring')
,redis   = require("redis");

var connected_socket = 0;

server.listen(8080);

var productCounter  = redis.createClient();     
productCounter.subscribe("productCounter");

productCounter.on("message", function(channel, message){
    console.log("%s, the message : %s", channel, message);
    io.sockets.emit(channel,message);
}

productCounter.on("unsubscribe", function(){
    //I think to decrease counter here, Shold I? and How?
}

io.sockets.on('connection', function (socket) {
    connected_socket++;
    socket_id = socket.id;
    console.log("["+socket_id+"] connected");

    socket.on('disconnect', function (socket) {
           connected_socket--;
           console.log("Client disconnected");
           productCounter.unsubscribe("productCounter");
    });

})

非常感谢您的回答!

【问题讨论】:

    标签: node.js redis socket.io real-time visitors


    【解决方案1】:

    如果访问者将您的网站用作没有 Socket.IO 的普通网站,那么您可能会重新考虑整个跟踪方法。 为了在没有任何可能导致性能问题的前端工作的情况下有效地做到这一点,请考虑以下方法:

    我会选择带有智能过期索引的 MongoDB(随意使用具有类似方法的 redis)(如果现在 - 时间戳将长于 10 秒,这将创建过期文档)
    db.views.ensureIndex({ timestamp: 1 }, { expireAfterSeconds: 10 })

    并且会为产品创建索引以便快速计数
    db.views.ensureIndex({ product: 1 })

    您可以使用以下结构创建文档:
    _id: '(int)userId'
    product: '(int)productId'
    timestamp: new Date() (have expire index on this one.)

    当用户查看 Product 时,PHP 会记录 userId (_id)、productId (product) 和 present datetime (timestamp)。使用带有 upsert 标志的更新,以便在未找到文档的情况下插入。 这将确保一个用户目前只能查看一个产品,并且有效地使记录过期并在用户导航时切换到另一个产品。
    db.views.count({ product: 42 }) - 将输出查看产品 42 的当前用户计数。

    【讨论】:

      猜你喜欢
      • 2016-04-12
      • 2011-10-19
      • 1970-01-01
      • 2013-05-30
      • 2017-04-16
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      相关资源
      最近更新 更多