I am new to these tecnologies.
I want to get realtime visitor for each products for my site. I mean a notify like "X users seeing this product".
Whenever an user connects to a product counter will be increased for this product and when disconnects counter will be decreased just for this product.
I tried to search a lots of documents but i got confused.
I am using Predis Library for PHP.
What i have done may totaly be wrong. I am not sure Where to put createClient , When to subscribe & When to unsubscribe.
What I have done yet:
On product detail page:
$key = "product_views_".$product_id;
$counter = $redis->incr($key);
$redis->publish("productCounter", json_encode(array("product_id"=> "1000", "counter"=> $counter )));
In 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");
});
})
Thanks a lot for your answers!
If visitors use your website as normal website without Socket.IO, then you might rethink the whole approach of tracking. In order to do it efficiently without any work on front-end that could lead to performance issues think of this approach:
I would choose MongoDB (feel free to use redis with similar approach) with smart expire indexing (this will create expire document if Now - timestamp will be longer then 10 seconds)
db.views.ensureIndex({ timestamp: 1 }, { expireAfterSeconds: 10 })
And would create index for product for fast counting
db.views.ensureIndex({ product: 1 })
You can create documents, with this structure:
_id: '(int)userId'
product: '(int)productId'
timestamp: new Date() (have expire index on this one.)
When user comes to view Product, PHP would record userId (_id), productId (product) and present datetime (timestamp). Use update with upsert flag in order to insert in case if document not found.
This will make sure that one user can view only one product at the moment, and will efficiently expire records as well as switch to another products if user navigated so.
db.views.count({ product: 42 })
- would output present count of users viewing product 42.