SalientAnimal Posted December 2, 2015 Share Posted December 2, 2015 Hi All, I have been searching for quite some time now for a script / process to check user online / offline status. I know there is no real "Ideal way" to check the status, as there could be a number of reasons for a user being "Offline / Online". My search for an updated way to check this has been fruitless and I was hoping that someone could either direct me to where I could read up on this, or perhaps give me some guidance. My thought process is that a user sessiontable would have to be created, this table will update when a user logs in in one column and logs out in another column... This way I can check when a user was last online, coupled with a current active session. The catch here is a user needs to physically logout... What of they don't logout? What if they go "Inactive" but are still online, so set an "Away" status. Any advice / guidance will be greatly appreciated. Thanks. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/ Share on other sites More sharing options...
Jacques1 Posted December 2, 2015 Share Posted December 2, 2015 I'd approach this from two directions: First off, you should have a timestamp column which you update whenever the user makes a standard HTTP request. On logout, you set the value to NULL. If the last update is within a certain time frame (e. g. 15 minutes), you consider the user active. Additionally, you should implement a “heartbeat” function in JavaScript. This function periodically makes an Ajax request (e. g. every 5 seconds), and the server saves the current timestamp in an additional column. If the last update is within a certain time frame, you consider the user active. The benefit of using both approaches at the same time is that the status is more accurate if JavaScript is turned on, but it still works if JavaScript is blocked. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527428 Share on other sites More sharing options...
SalientAnimal Posted December 2, 2015 Author Share Posted December 2, 2015 Based on what you have said Jacques, would it be correct in assuming that you could use the Ajax heartbeat as an activity status, i.e. online, away, offline. The HTTP request, would be on every single page and would therefore only update if and when some sort of link is clicked on the page? So based on this I would have a table with a structure such as memberID, activity_status, heartbeat, last_active The columns will function as follows: activity_status - HTTP request timestamp, heartbeat - Ajax request timestamp, last_active - the time of the logout request. How will it identify if a user goes offline? The HTTP request will only update when a request is sent, but what happens if JavaScript is blocked and the user simply closes the browser? What are your thoughts? Any idea where I could read up on a good tutorial for implementing what you have mentioned? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527433 Share on other sites More sharing options...
gizmola Posted December 2, 2015 Share Posted December 2, 2015 The modern way of doing this stuff is websockets. I would look into that. There are also SaaS web sockets server support from companies like https://pusher.com I've used Pusher in the past successfully, although there are others now you might investigate. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527438 Share on other sites More sharing options...
SalientAnimal Posted December 2, 2015 Author Share Posted December 2, 2015 The modern way of doing this stuff is websockets. I would look into that. There are also SaaS web sockets server support from companies like https://pusher.com I've used Pusher in the past successfully, although there are others now you might investigate. Gizmola, I have two questions: How do I know if my webhost will support websockets to perform this function? If I decide to run my site as an intranet, how would I gain access to the websockets? I'm looking for a solution that it rather easy to implement and understand, but from what I have read thus far I am left scratching my head... Thanks Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527447 Share on other sites More sharing options...
Jacques1 Posted December 2, 2015 Share Posted December 2, 2015 By far the easiest approach is Ajax, because that's literally just a few lines of code with no special setup whatsoever. You actually just need one timestamp column and one boolean column to indicate whether the user supports the JavaScript heartbeat feature. The query to select the currently active users would then look like this: SELECT user_id -- or whatever you need FROM users WHERE last_activity >= IF(supports_heartbeat, NOW() - INTERVAL 10 SECOND, NOW() - INTERVAL 15 MINUTE) ; The HTTP request, would be on every single page and would therefore only update if and when some sort of link is clicked on the page? You do the update in every script whenever you resume an active session. Then you'll cover both page views (GET requests) and actions (POST requests). How will it identify if a user goes offline? The user is considered offline in one of those three cases: they explicitly log out they support the heartbeat feature but haven't sent a heartbeat within the last 10 seconds they don't support the heartbeat feature and haven't made a request within the last 15 minutes The HTTP request will only update when a request is sent, but what happens if JavaScript is blocked and the user simply closes the browser? If JavaScript is blocked, the heartbeat feature will simply not be activated. Closing the browser has no effect, because there may still be other tabs/windows, maybe even in a different browser. Any idea where I could read up on a good tutorial for implementing what you have mentioned? The implementation is very easy and straightforward, so I'd just give it a try. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527454 Share on other sites More sharing options...
SalientAnimal Posted December 3, 2015 Author Share Posted December 3, 2015 Thanks again Jacques, I'm going to get cracking on trying to get this to work. I am assuming that with this solution each user would only appear in the activity table once? Once I have the heartbeat up and running, the next thing I want to achieve, is to use this as a tracking system to see when a user logs in / out on a daily basis and use it as a register. Would you recommend using the same table to track this information? Or should I then look at doing this in a completely separate table? I was thinking of possibly creating a view and updating it daily with the first login event of a day, and last logout event. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527463 Share on other sites More sharing options...
QuickOldCar Posted December 3, 2015 Share Posted December 3, 2015 The whole checking for users online is a big resource hog, especially if have a lot of users online. Something like a last activity is fine in my opinion. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527464 Share on other sites More sharing options...
SalientAnimal Posted December 3, 2015 Author Share Posted December 3, 2015 (edited) I have managed to find a bit of code which shows the activity status to the user who is logged in. If I navigate to a different tab, it picks up that I have navigated away, and sets my status as such, the question now is, How do I pass this information to the database so that I can use it to show other users who is online? How would I show an online icon (small green / yellow / red) instead of echoing a new row of text? I am using the following code as an include file (I think it is important to state that this is not my own code, so I am not entirely sure how it functions): <html> <head> <title>Idle.Js Test</title> <script src="../js/jquery.min.js"></script> <script src="../js/idle.js"></script> <script> $(function() { function setMessage(msg) { $('#ActivityList').append("<li>" + new Date().toTimeString() + ": " + msg + "</li>"); } var awayCallback = function() { setMessage("away"); }; var awayBackCallback = function() { setMessage("back"); }; var hiddenCallback = function() { setMessage("User is not looking at page"); }; var visibleCallback = function(){ setMessage("User started looking at page again") }; var idle = new Idle({ onHidden : hiddenCallback, onVisible : visibleCallback, onAway : awayCallback, onAwayBack : awayBackCallback, awayTimeout : $('#Timeout').val() //away with default value of the textbox }).start(); $('#Timeout').keydown(function(e) { if(e.keyCode == 13) { var timeout = $(this).val(); setMessage("Timeout changed to: " + timeout); idle.setAwayTimeout(timeout); } }) }); </script> <style> #ActivityList { border: 1px solid #ccc; padding: 5px; width: 400px; } #ActivityList li { border-bottom: 1px solid #eee; margin: 5px 0; } </style> </head> <body> <label for="Timeout">Set timeout</label> <input id="Timeout" type="text" value="10000" /> <ul id="ActivityList"></ul> </body> </html> Idle.js file: (function() { var Idle; if (!document.addEventListener) { if (document.attachEvent) { document.addEventListener = function(event, callback, useCapture) { return document.attachEvent("on" + event, callback, useCapture); }; } else { document.addEventListener = function() { return {}; }; } } if (!document.removeEventListener) { if (document.detachEvent) { document.removeEventListener = function(event, callback) { return document.detachEvent("on" + event, callback); }; } else { document.removeEventListener = function() { return {}; }; } } "use strict"; Idle = {}; Idle = (function() { Idle.isAway = false; Idle.awayTimeout = 3000; Idle.awayTimestamp = 0; Idle.awayTimer = null; Idle.onAway = null; Idle.onAwayBack = null; Idle.onVisible = null; Idle.onHidden = null; function Idle(options) { var activeMethod, activity; if (options) { this.awayTimeout = parseInt(options.awayTimeout, 10); this.onAway = options.onAway; this.onAwayBack = options.onAwayBack; this.onVisible = options.onVisible; this.onHidden = options.onHidden; } activity = this; activeMethod = function() { return activity.onActive(); }; window.onclick = activeMethod; window.onmousemove = activeMethod; window.onmouseenter = activeMethod; window.onkeydown = activeMethod; window.onscroll = activeMethod; window.onmousewheel = activeMethod; } Idle.prototype.onActive = function() { this.awayTimestamp = new Date().getTime() + this.awayTimeout; if (this.isAway) { if (this.onAwayBack) { this.onAwayBack(); } this.start(); } this.isAway = false; return true; }; Idle.prototype.start = function() { var activity; if (!this.listener) { this.listener = (function() { return activity.handleVisibilityChange(); }); document.addEventListener("visibilitychange", this.listener, false); document.addEventListener("webkitvisibilitychange", this.listener, false); document.addEventListener("msvisibilitychange", this.listener, false); } this.awayTimestamp = new Date().getTime() + this.awayTimeout; if (this.awayTimer !== null) { clearTimeout(this.awayTimer); } activity = this; this.awayTimer = setTimeout((function() { return activity.checkAway(); }), this.awayTimeout + 100); return this; }; Idle.prototype.stop = function() { if (this.awayTimer !== null) { clearTimeout(this.awayTimer); } if (this.listener !== null) { document.removeEventListener("visibilitychange", this.listener); document.removeEventListener("webkitvisibilitychange", this.listener); document.removeEventListener("msvisibilitychange", this.listener); this.listener = null; } return this; }; Idle.prototype.setAwayTimeout = function(ms) { this.awayTimeout = parseInt(ms, 10); return this; }; Idle.prototype.checkAway = function() { var activity, t; t = new Date().getTime(); if (t < this.awayTimestamp) { this.isAway = false; activity = this; this.awayTimer = setTimeout((function() { return activity.checkAway(); }), this.awayTimestamp - t + 100); return; } if (this.awayTimer !== null) { clearTimeout(this.awayTimer); } this.isAway = true; if (this.onAway) { return this.onAway(); } }; Idle.prototype.handleVisibilityChange = function() { if (document.hidden || document.msHidden || document.webkitHidden) { if (this.onHidden) { return this.onHidden(); } } else { if (this.onVisible) { return this.onVisible(); } } }; return Idle; })(); if (typeof define === 'function' && define.amd) { define([], Idle); } else if (typeof exports === 'object') { module.exports = Idle; } else { window.Idle = Idle; } }).call(this); Edited December 3, 2015 by SalientAnimal Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527491 Share on other sites More sharing options...
gizmola Posted December 3, 2015 Share Posted December 3, 2015 Web sockets is the evolution of ajax requests (and Long Polling), and has features that improve on things in ajax that are not ideal for persistent connections. There are useful things available in Websockets that support pub/sub which for something like a user list is really nice. In all cases the client side technology is javascript. On the server side, there are various ways to implement a web socket server, although web sockets have largely grown up along with Node.js and frequently people who roll their own solution do so with Node. A way around the entire requirement for a separate web socket server process is to use Pusher, which acts as a proxy for you. It accepts the web socket connections on your behalf from your clients and makes calls to your server to get the actual information needed to service the connection. They have lots of code example and it's not a bad idea to try them out to get your feet wet with web sockets. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527502 Share on other sites More sharing options...
SalientAnimal Posted December 3, 2015 Author Share Posted December 3, 2015 Gizmola, I spent the entire day today searching for both an Ajax and Websocket solution. I would very much like to implement the websocket solution, but I was not able to find a working solution with code that I could easily implement into my page. If you could direct me to a good working example which would help me in achieving my goals, I would really appreciate that. Some more info about the site that I am developing is: When a user has been registered, they will be assigned to a team / group, when the group leader signs in they will need to see only their team members who are both online and offline. The online members should have a little green light next to their names and the offline members should have a red light. Members who are in an away state should reflect an orange light. For this reason, I will need to be looking up certain information in my database, like which team they belong to and return this id along with the users status to the group leader. Regular users should be able to see all members status. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527505 Share on other sites More sharing options...
SalientAnimal Posted December 3, 2015 Author Share Posted December 3, 2015 I forgot to mention that I did also have a look at Pusher last night, but I am left horribly confused trying to put things together. The Pusher option is really nice for when the site runs completely online, however there may be instances where my entire site is actually going to run on a intranet which won't have access to and internet connection. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527507 Share on other sites More sharing options...
gizmola Posted December 4, 2015 Share Posted December 4, 2015 Hi, Since Pusher isn't an option for you, here is an option to look at that will allow you to keep your server side codebase in PHP: http://socketo.me They have a simple proof of concept/tutorial. I'd recommend following those steps and get everything installed and tested, and from there it would just be a matter of adding your specific application logic. Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527532 Share on other sites More sharing options...
SalientAnimal Posted December 4, 2015 Author Share Posted December 4, 2015 Thanks Gizmola, let me see if I can get this approach working Quote Link to comment https://forums.phpfreaks.com/topic/299618-check-user-online-offline-status/#findComment-1527535 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.