实时访问者与nodejs&redis&socket.io&php

我对这些技术不熟悉。

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

每当用户连接到一个产品柜台将增加本产品,当断开计数器将减less只为这个产品。

我试图search大量的文件,但我感到困惑。

我正在使用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"); }); }) 

非常感谢你的回答!

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

我会selectMongoDB(随意使用redis类似的方法)与智能到期索引(这将创build过期文件,如果现在时间戳会超过10秒)
db.views.ensureIndex({ timestamp: 1 }, { expireAfterSeconds: 10 })

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

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

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