How to know when user closes browser? Chat application - php

I have a simple chat client set up that allows users to login with a username and stores the messages they write in an sql database. Every 3 seconds, the database simply prints of all the rows. So it's basically a chat client.
I'd like to keep a list of who's online. How can I do this? How can I sense when someone has closed the browser?
Right now I'm pulling the username as
$name = $_COOKIE["name"];
and if this value is empty, I know they left. But once they left, it's too late to know what their username was so I can't keep track of who exactly left.
Ideas? I'm fairly new to php, javascript, and html, so keep that in mind :)

It is hard to send a last request to the server when someone closes the window, since Browsers usually don't wait for JS execution to finish when the user wants the window closed (as is the case with onbeforeunload).
Whenever I am confronted with a situation like this, I tend to use onbeforeunload to send a final request (which happens fast and usually finishes before browser window is closed), but also implement a timeout feature. The timeout feature would work as follows:
Everytime the user sends something to the server, the server recognizes this as 'still there'. At the same time, the client sets a timer of, say, 45 seconds. If the user does not type anything for 45 seconds, the client sends a 'still alive' signal on its own to stay connected.
Now, the server should execute a removeInactive() routine every 60 seconds (allow 15 seconds slow-connection margin, hence the 45/60 seconds) which removes any users who haven't sent a 'still alive' signal in the last 60 seconds.
This system worked fine for me so far, you could try it out for yourself.

Assuming your using AJAX to pull in the chat messages every X seconds, update your table of users at the time with the current timestamp for that user. Then anyone who has a timestamp say older than 10 seconds, you will know they have left the page.

put online users in a table that will have a field named like 'lastSeen' update this field every few seconds with ajax call..
ajax call be made someting like this :
window.setInterval(function() {
$.ajax({
url: _URL_ENGINE + "/updateLastSeen/?userid=" + userID,
success: function(data) {
}
});
}, 2000); // 2000 means 2 seconds
now to query the list of online players u can query them like
select * from players WHERE lastSeen > DATE_SUB(NOW(), interval 40 SECOND)
hope this helps

Use the onbeforeunload event.

You could possibly attach to the onunload event in javascript. Have a look at http://help.dottoro.com/ljflhicd.php for full details.

Refer these links. Sure this is a light for ur darkness.
Link1:
http://www.daniweb.com/forums/thread252828.html
Link2:
http://phpeasystep.com/phptu/9.html

Related

How To Write To Database User's Logout Timestamp When Browser Is Closed / Crash

I have a table on my database called 'Log'. This Log table contains ID, Username, LoginTime and LogoutTime. That's all.
It's really easy to INSERT into ID, Username and LoginTime columns...
But dealing with LogoutTime, I was thinking there will be 2 condition :
User click logout button >> PROBLEM SOLVED, I can easily put INSERT script on my logout.php to handle LogoutTime column.
User just run away from my website by clicking close button of their browser >> THIS WILL CAUSE A PROBLEM. How can I write to LogoutTime column in this situation like this?
can it be handle by PHP only? I mean, doesn't have to use jQuery... Thanks before.
The most common solution to get this done is by using a timeout. So you run periodically a cron which checks whether there are users which are not active anymore. For example it can be no requests done for the last half hour. Then add the logout time at that moment.
So every action update the user session with the last request time so you know when they have a timeout.
Controlling 100% a closing browser is not possible. Think for example about a power failure at the client computer, you will get nothing back for sure.
You can implement something similar to this, the time can be different according to your need
if (isset($_SESSION['browser_last_activity']) && (time() - $_SESSION['browser_last_activity'] > 1800)) {
// request 30 minates ago
// set the logout time here
}
$_SESSION['browser_last_activity'] = time(); // update last activity time
But there is no way you can implement functionality 100% meet your requirements with php.
And with javascript you can try with onbeforeunload, it is good practice than do it with javascript and not in php because of overhead reasons.
In IE you can try something like this:
< body onbeforeunload="alert('Closed!');">

Counting the time a user has been connected to a site

At the moment I'm using this SQL to check if a user is connected:
date_add(last_activity, INTERVAL 3 MINUTE) > NOW()
This is passive and will only trigger when a page is loaded.
What I'd like to do is a system that checks if a user has remained connected during a given span of time and give them bonus points.
What do you suggest to achieve this? Use polling or another approach?
You need to use some kind of java script that will report activity using ajax to your site in intervals of like 1 min. You need to implement some sort of mechanism to check if user is active, like if the mouse moves or page is scrolled, because some users can use the same page for long times. If the page is not used since the last min(should be a global var in javascript, set to true every mouse move, and to false every time a message is sent) you don't send a message.
When you receive the ajax notifications in the server you check the time between the last ajax notification(should be stored in database) and current notification and if its smaller than an interval (maybe 2 mins) give the user points for it.
As said you can use AJAX and alternatively the Refresh META tag. Note that if I see a browser tab constantly refreshing, I close it as it is distracting. Of course, if you're offering a service that requires frequent refreshes (chat / shoutbox, ticker) then it's less disturbing.
I currently have 14 tabs open, some of which for days which I haven't really looked at, so you gotta ask how valuable your information is. As far as I know, javascript is unable to get the current mouse position if it's not moving over something that has the mousemove event handled, so implementing "is the page in view and the user moving her mouse" may prove to fire a lot of events when user is active.
I may be oversimplifying here, and this probably won't help much if you're trying to charge for time on the site or something like that, but this is something google analytics takes care of. Time on site is a metric they actively record.
Ok. So here is my idea. As I mentioned in comment my way would be javascript timeout and AJAX.
So the idea would be something like this:
Make a global variable for mouse position.
Set timeout for function to fire in around 10 second intervals (which can grow in time).
Function compares last mouse position with current mouse position. If it has changed user is presumably active.
Update global variable for mouse position. And send data to server-side.
Rinse and repeat...
Actually thing that changed can be anything if you want, but mouse position would be most suiting I think.

Is this the best way to update user status?

Status as in online/offline..
When a user enters onto a page, it records the current time and puts it in the database.. if 5 minutes passes since their last action, it shows them as offline?
You can use JavaScript to time the five minutes, then use AJAX to call a PHP script that updates the database.
window.onLoad = function(){
setTimeout(UpdateDB,1000*60*5);
}
function UpdateDB(){
// AJAX call...
}
This would be a good way to start. You can easily check the period of inactivity.
It would be relatively simple for you to set up an AJAX ping to your server on a long interval~ so that as long as the user's browser has your site loaded, it's still pinging it's status as online.

Log what page the user is currently on

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.

After 30 seconds, update MYSQL database

I've been looking around here on SO and Googling, however I can't find anything that fits my description.
What I want to do is update the database if the page has not been refreshed after 30 seconds. I want to email a person with the contents of a form {submitted by a different user} (I can do that) IF the person has NOT visited the page (I can do that) within the last 30 seconds.
What I've tried to do is make the page that should be visited refresh every 30 seconds, and so I figured if I did something like after 31 seconds, edit the database (so if the refreshed page was not refreshed, the database editing would run).
I'm sorry if this sounds complicated, there's probably a better way to do this, but I'm not sure how.
The bigger picture is I'm trying to make a 'on-duty' sort of thing, so that if the person is not actively looking at the page, they will get emailed with whatever the contents of the form is. The page will contain a table of all the entered form results.
You could update the database by creating a record with a timestamp every time the user refreshes the page. Then, you can have a PHP worker that looks regularely in the database if the timestamp is older than 30 seconds, and starts the e-mail.
I can't provide php solution for the server-side part of the job. But basically you need to set up javascript timer (eg. jquery timeout) and after 30seconds do the ajax call that will do what you want on the server (save something to db, send email and so on).
I hope I got your point and my advice will help you somehow.
maybe use an AJAX call every 30 secs based on the setTimeout javascript function?
http://www.w3schools.com/js/js_timing.asp
function timedCount()
{
# ajax call
t=setTimeout("timedCount()",30000);
}
I would suggest using javascript like this:
window.setTimeout("location.reload(true);", 3000);
This is of course if you desperately need to reload, but the user will obviously be mad that you reload the window for him.

Categories