Log what page the user is currently on - php

I have a chatroom on my website. I want to compile a list of online users in the chatroom.
What is the best way to do this?
Would it be to log the last page the user visited and if it was that page, they are in the chatroom?
What different techniques can be used to do this?
Thanks

If you're using Comet in your chat application, then you'll have a channel open to the server, which would be bound to the client side as an open HTTP request.
As long as that request is open, the user is in the room. If the request closes, then the user is no longer in the room.

I would use sessions javascript library to record each page the user has visited and then retrieve those values in your chat client via javascript.
include the library on each page.
in the sessvars object, make an array sessvars.visited = []; [if sessvars.visited is not already an array]
Now on each page do something like this sessvars.visited[] = location.href
On the chat client page, use javascript to iterate through sessvars.visited to obtain all the URLs. For example, To list out the URLs in HTML w/ Jquery do the following:
var urlList = '';
$.each(sessvars.visited, function(key, value){
urlList += value + '<br />';
})
Note: Sessvars is an alternative to Cookies that has a very large capacity (10mb in most browsers). However, session data is only available in an active window. Information is lost once the window is closed, and as far as I know cannot be queried from other windows. So if chat is open in a different window than they were browsing in, this will not work.

You should make a javascript request to the server every x seconds.
You already have to do this (for retrieving the ongoing chat conversation and the list of users participating).
On the server side you know what users are on because of this request. You just have to log these requests.

Yshout works by doing an AJAX request against yshout/yshout.php every 6 seconds. Add a bit of code to yshout.php to track how many unique users it's seen in the last 10 seconds, and you should be set.
Edit: you want the names of everyone active in the chatroom? I'd be tempted to add a database table for this - every time they hit yshout.php, add a name+timestamp entry and delete all entries more than 10 seconds old. Then query with GROUP BY name to get unique users.
Edit 2: The chat client already does an AJAX request on yshout.php every six seconds. All you have to do is add a snippet of PHP code inside the 'if (isset($_POST['reqFor']))' clause (the bit that responds to the AJAX requests).
Keep it brief! Remember, it's going to get hammered on something like 150 times per minute.

Related

Username has left the chat message when his session ends?

Basically I have a chat, using AJAX, PHP.
I let guests login by filling their name and clicking login.
It fills the session $_SESSION['guest'].
Now, when they close their browsers, or something, once the session ends, I want it to say in the chat
"The username has left the chat".
But I am not sure on how would I do this.
Any ways to do it? Maybe I could fill an array of users that were active in the past 5 minutes, if not, remove from the array and it will kick them off the chat.
Any ideas?
You could have an array of users in the backend with the timestamp of the last ping.
Then, the clients end can update the backend using ajax by sending a new timestamp every so many seconds.
Whilst your backend is being updated by one of the users, your backend can do a check on all users checking the last timestamp sent to the current time, if its over 2 minutes or something you can tell they have left the chat and output the message.
Without a direct connection to the browser, you won't be able to actively tell if they're connected. I'd suggest a ping-like solution, requiring the browser to ping the server every n seconds to keep the chat "alive".
If the browser doesn't "check in" with the server, the server assumes they've disconnected and reports back to the other participant.
That said, if you're able to dive a little deeper, Google "javascript real-time chat" and you'll have several paths to success.
Add a jQuery .unload() event to your chat client. When they navigate away from the chat it will be fired and you can use it to send the last bit of data to display that message.
Here is the documentation: Link.
Example:
$(window).unload(function() {
//send message to server informing it of client leaving
});

How to update page content while multiple users view it at the same time in PHP?

My page is visited by multiple users at the same time.
User 1: visits the page and changes the name of title
User 2: user 2 was already on that page but sees the old title, the title automatically has to be updated to new title.
I know i can simply use AJAX to call every 5 minutes, but im trying to see if there is any other way possible that fires an event to all instances of the page opened by different users that if one of them is updated all other pages get automatically updated with latest data without the wait of 5 minute ajax call. Ajax seems inefficient since it will do many ajax calls and also what happens if user 1 updates title while user 2 updates title as well before user 2's page has been updated with 5 minute ajax call.
Not asking for a code, just need an advise whether I should keep using AJAX calls every 5 minutes and be happy with it or there is a better solution.
Try investigating web sockets for real time, two way communication between server and browser.
http://socketo.me/
I'm in the early stages of working with it myself but it seems like a solution that would fit your requirements.
Also, maybe look at push notifications
e.g. http://www.pubnub.com/blog/php-push-api-walkthrough

How to get around server flooding by users opening countless tabs?

I have some kind of chat/forum application that checks for new messages using periodic polling (every 15 seconds) using jquery ajax. I was wondering if i can get around the issue of users who try to be 'funny' by loading several same browser instances, with lots of tabs, all pointing to the same application. Each tab is sending an ajax request, which potentially can overflow a server if several users start to do the same thing.
I do store sessions in a table, along with the last access time and IP address, which works fine as long as users don't use the same browser. I could store a unique identifyer that is sent using the ajax POST or GET request, but that would give problems if a regular (non abusing) user refreshes his page, which would then create a new identifyer.
This is not a real problem yet, but better catch it before someone thinks of abusing the system like this :) Any idea how to do this?
One option could be to fetch data like so:
Your script is preparing to poll data. Before executing the request, write (with LocalStorage), a value saying that you're going to fetch data. localStorage.setItem("last-request-timestamp", new Date().getTime());
Poll for data. You get a result. Write that result to the localStorage: localStorage.setItem("latest-messages", ajax_result);
Check if a page is preparing to poll data by checking if localStorage.getItem("last-request-timestamp") is longer than 15 seconds ago. If so, go to step 1. If not, wait 15 seconds and check again.
Regardless if the current page polled for data or not, check the latest-messages variable and update the page.
Other pages will of course share the localStorage data. They won't get data if another page is fetching at the moment. If page #1 is closed, one of the other pages will continue to fetch data.
I haven't used LocalStorage before, but browser support seems decent enough. You should also be able to just use it as a key-value array: localStorage["last-request-timestamp"].
You can only store strings in localStorage, but you can of course serialize it into JSON.
Not sure if it is do-able in javascript. You can check if the tab is active. And only do the ajax on the active tab?
I have the similar problem. Now I force all users to log in (it means i have their e-mails). Also i setup connections limit per account and request limit per connection, after 5 overflows i ask user to enter captcha, then i block account for a 30 min and send e-mail with password recovery link. It's not a clear solution but for now it works for me.
UPD:
The simplest way to do this is to use cookie or session storage. I use cookies. The algorithm is simple:
User login on web.
Check is there any opened session for this user,
is opened, then delete the other session or trigger exception or
switch to that session, you have decide your own the desired
behavior.
Create session id for user and store it in database.
Increase sessions counter field for specific user to detect opened
sessions, so now it doesn't matter is there one browser in use
or many.
Update last access mark (i use microtime(true) + $delay and mysql
decimal(14,4)). Send it to user
Send id to client
On each request:
Search for session by passed id in $_COOKIE.
Check last access mark. If it less then microtime(true) it means that client send requests to frequent, so decide yourself what to do, increase the mark, for example microtime(true) + $delay + $penalty or drop whole session or trigger error. The behavior depends of your application.
Why not throw something like Memcached/Redis at the problem? Cache a response with a 10-15s lifetime and avoid as much processing as possible.

How to refresh the Server or Database Table Values for every X Seconds

Ok i am tryin to make a Chatting application where users can chat with each other if theyr logged in to the website. I have set up everything except a little working which i am not able to write.
In my example : 2 users are chatting with each other : User A and User B
When User A submits a comment in the Chat Window , then the whole div containing the Comments should be refreshed not only at User A's side but also at User B's side so that when User A submits the comment, User B should be able to see it.
In short refreshing the div on every users page when a new record is added to the database table.
Im good in PHP, Jquery, AJAX.
Every x seconds use Ajax to check for new messages and if there is a new message, write it in the div.
There is no way for the server to tell the client a new message was posted. The client has to ask the server.
If you're comfortable restricting your users to new technologies, your best bet is to look into HTML5 websocket API. It's still a bit green around the gills, but it's certainly the way these things will be done in the near future. Kaazing's default example is a chat client, actually.
On the server side, there are implementations for websockets in JavaScript (Node.js), Java, and other technologies, but I'm not sure about PHP.
If you don't want to use websockets, research techniques that fall under the name "COMET" or search for "long polling". These will be far more responsive than a time interval.
If on the other hand you don't need it to be super-responsive, you could just use setInterval to have both clients poll the server for changes.
DC's answer is correct, if you are looking for an AJAX polling solution. This could be done with a simple JavaScript Interval.
However, polling is not light on resources as there are going to be a lot of duplicate content requests - and you would need to poll frequently to make the chat feel as though it is real-time.
If you would like to push data to the client from the server, I would look into writing this application using web sockets. NodeJS would be perfect for what you are trying to achieve, depending on what browsers you are wanting to support.
you need a timeout function like so:
function updateChatWindow(){
var xhr = $.ajax({
url : /* controller url */,
})
.done(function(response){
/** do something with the response the server gave you back **/
});
.fail(function(response){
/** handle a lost connection is some way, maybe show a message to the user, or retry request */
})
.then(function(){
periodicRefresh();
});
}
var timeoutFunction; //idealy, this will be inside a javascript object
//starts a refresh (in 500ms)
function periodicRefresh(){
timeoutFunction = setTimeout(updateChatWindow,500);
}
//stops the refresh from happening, see below why
function clearRefresh(){
clearTimeout(timeoutFunction);
}
var inputElement = $(/** the input area where the user types text **/);
inputElement.keyup(function(e){
if(e.keyCode==13){ // or whatever the e.???==13 was to check for enter
clearRefresh();
/** submit new chat line **/
updateChatWindow();
});
updateChatWindow();
Recap:
1) Have a ajax call that will update the window
2) Have a timer function that will store within it a timeout variable that will trigger a refresh of the content (the ajax call from 1)
3) Have the ability to cancel that request (because users type text, and after they hit enter, you should refresh the chat window no matter what)
4) Have the ability to stop the timeout function somehow to allow 3) to happen.

How to calculate how much time the user is on a web page?

im making some statistic codes for my website (im a php developper). I want to calculate how many seconds/minutes the web user stay on any page (like google analytics do) but i have no idea of how to make this. Thanks for any help or scripts!
How are you gathering the data? The common options would be instrumenting the page using javascript, looking at webserver log files, in the server-side request handler or sniffing the TCP/IP traffic.
Doing it "like Google Analytics" implies the former. In which case the way to do it would be to grab a timestamp as soon as possible when the page loads (rather than waiting for page ready / onload event) and compare that value with the previous tiestamp (so you'd probably store that in a cookie). Then you need some way to send this back serverside, and a way of recording and reporting on the data.
Note that trying to fire an ajax call as the user leaves the page, e.g. via onunload, will not work reliably (the page launching the request is at the end of its lifecycle). The important thing here is the ASYNCHRONOUS part. And making a synchronous call will just have the effect of slowing down the website.
You might want to have a look at Yahoo Boomerang - although it doesn't support dwell time measurements out of the box, it's easy to extend. For a backend, you could do a lot worse than Graphite
You can fire an unload event in javascript when the user leaves the page, which sends an Ajax request to your server. Since this may not work in all browsers, especially if the network latency is high, also have a ping script (also with Ajax) which calls your statistics system once in a while as long as the user stays on the page (for example, every 10-60 seconds depending on the resolution you want).
If you want to do it in serverside i.e in php then probably you would need a table allocated for this. say "analytic"
First you need to add this script in every pages. that inserts these data into the table analytic which is $_SERVER['http_referer'] , current timestamp, remote address and current page URL.
Now the calculation part.
basically when a user first lands in your page $_SERVER['http_referer'] wouldnt be from your domain. Then keep the timestamp as the start time.
Now check the next time stamp. If the http_referer is same as previous records page URL then find the difference in the time stamp to know how much the user has stayed in a page.
More or less what am trying to say is find the time between each request from the user.
Disadvantage of this method: When user lands in a page closes it. its impossible to find the time on your site.
A quick and easy method I came up with is pretty useful.
On every page of a site where I want to track time on page, I include a tracker script.
I grab as much info as I can, and make a database entry, including the referrer, the requested/loaded page, user-agent, ip, timestamp, etc.
These timestamps, in conjunction with the user's ip, can be used to determine the time the user was on the previous page (including load time of current page).
The only drawback is that I can't determine time on the last page they visit (which isn't always a bad thing, I can reduce tracking idle time).
Bounces are identified by single entries by a given ip within a specified time period (an hour would probably be sufficient).
At page load create a date object, then when the page unloads create another and substract them. After that you can do an AJAX request to your tracking server, sending the elapsed time.
var startTime = new Date();
var endTime;
window.onunload = function()
{
endTime = new Date();
var elapsedSeconds = endTime.getTime() - startTime.getTime();
//Do the ajax request, sending elapsedSeconds
}

Categories