2013-06-25 79 views
2

我是这些tecnologies的新手。nodejs&redis&socket.io的实时访问者&php

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

无论何时用户连接到产品,本产品的计数器都会增加,并且当断开连接计数器的数量将减少到只有该产品。

我试图搜索大量的文件,但我很困惑。

我正在使用Predis Library for PHP。

我所做的事情可能总是错的。 我不确定在哪里放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"); 
    }); 

}) 

非常感谢您的回答!

回答

0

如果访问者使用您的网站作为没有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.)

当用户来到查看产品,PHP将记录用户ID(_id),的productId(产品)和本日期时间(时间戳)。如果找不到文档,请使用upsert标志更新以便插入。 这将确保一个用户目前只能查看一个产品,并且会有效地将记录过期并在用户导航时切换到其他产品。
db.views.count({ product: 42 }) - 将输出当前查看产品42的用户数。