Few issues with creating a web based chat system - php

I've decided to create a web based chat system for the experience. I'm using a mixture of AJAX(jQuery), PHP, and JSON to transfer the data. Now that I've started thinking about certain things, I've come to a mind block.
Right now, I use javascript to post the last loaded message id to a php file that queries the data and echoes new posts in json and then displays those posts in order on the page. However, the dates don't reflect the current time for the user. Since I use php to get the current time, I have no idea how to display the correct time to the user which takes into account of their time zone. Second, how would I incorporate a who's online list with this method? I could create a separate table and update it when a user creates a session and delete their name when they end the session; but what if they don't close it properly? Should I just add their last sent message into the the table and if it's been about 5 minutes since their last message consider the user disconnected? Lastly, is the method I'm using to collect new posts efficient? This there a better way to go about this? I appreciate any input.

This seems related: Determine a User's Timezone
I'm going to make you go there for the code snip so you give proper credit with your upvotes.
I get the impression that Javascript is the best/easiest way to get that data.
What I would probably do is use GMT or some other fixed time zone for all your server stuff and then just adjust that with js once it hits the browser depending on their time zone. Either that or just collect it once at the start of the conversation and adjust your output accordingly. There might be advantages to either way.
Edit:
Oh yeah, about the "who's online" I think you're headed in the right direction. I might suggest 2 lists. "Who's active" and "Who was active recently"
That way you can put people inactive after 5 mins and consider them disconnected after 10 or something. I guess it's about the same but it seems more accurate to me somehow.
The other option would be to set an ajax request to automatically fire of a request every minute or so. When they stop then you know the user is gone.

Related

Building a live database (approach)

I just want a approach on how to build a database with live records, so don't just downvote. I don't expect any code.
At the moment I have a MySql database with about 2 thousand users, they are are getting more though. Each player/user has several points, which are increasing or decreasing by certain actions.
My goal is that this database gets refreshed about every second and the user with more points move up and others move down... and so on
My question is, what is the best approach for this "live database" where records have to be updated every second. In MySql I can run time based actions which are executing a SQL command but this isn't the greatest way I think. Can someone suggest a good way to handle this? E.g. other Database providers like MongoDB or anything else?
EDIT
This doesn't work client side, so I can't simply push/post it into the databse due some time based events. For explanation: A user is training his character in the application. This training (to get 1 level up) takes 12 hours. After the time is elapsed the record should be updated in the database AUTOMATICALLY also if the user doesn't send a post request by his self (if the user is not logged in) other users should see the updated data in his profile.
You need to accept the fact that rankings will be stale to some extent. Your predicament is no different than any other gaming platform (or SO rankings for that matter). Business decisions were put in place and constantly get reviewed for the level of staleness. Take the leaderboards on tags here, for instance. Or the recent change that has profile pages updated a lot more frequently, versus around 4AM GMT.
Consider the use of MySQL Events. It is built-in functionality that replaces the need for cron tasks. I have 3 event-related links off my profile page if interested. You could calculate ranks on a timed schedule (your tolerance for staleness) and the users' requests for them would be fast (faster than the below from Gordon). On the con-side, they are stale.
Consider not saving (writing) rank info but rather focus just on filling in the slots of your other data. And get your rankings on the fly. As an example, see this rankings answer here from Gordon. It is dynamic, runs upon request with at least at that moment non-staleness, and would not require Events.
Know that only you should decide what is tolerable for the UX.

Executing function to alter database every 15 minutes

I am currently working on a project that runs online tournaments. Normally admins of the site will generate brackets when it is time for the tournaments to start, but we have run into inconsistent start times, etc. and i am looking into proper ways to automate this process.
I have looked into running cronjobs every x min to check if a bracket needs to be generated but i am worried about issue when it comes to overlapping cronjobs, having to create/manage cronjobs through cpanel etc.
I was thinking about other solutions and thought it would be great if a user could load a page, the backend checks timestamps and determines if the bracket should be generated. An event is then fired/set to begin the auto-generation process elsewhere so it does not impact user load times. I just do not know the best route of going about this.
PS: I just need an idea of the direction i should be looking into so i can learn how to solve this issue i am not looking to copy and paste code. I just haven't been able to find anything. All of my search results provide cronjob examples.
EDIT
After thinking about things could using this work?
$(document).ready(function() {
$.ajax('Full Url Path Here');
})
I don't need to pass user input, or return any data i simply need a way to fire an event, it would be easy to include this only when needed via a helper class. Also i won't necessarily have to worry about users attempting to access i can restrict the route to ajax only requests and since nothing is needed/used on input or returned as output what can happen?
You could do it everytime a user loads a page (idea not tested, but theoretically possible):
1) Create a file and store the timestamp of the last time you updated the database.
2) Everytime a user loads a page, read that timestamp and check if 15 minutes passed.
3) If 15 minutes passed: Run a background script (with shell_exec?) that will do what you want and update the timestamp when it's done executing.
One obvious flaw with this system is that if you have no visitors in let's say a 30 minute frame, you will miss 2 updates. Though I guess that if you have no visitors you also have no point in generating brackets?

Running a function/script per user on the server side

I'm working on a basic lamp(willing to change) website , and I currently need a way to run some function on the server that runs for several hours per user, and every X hours it needs to query the mysql database to see if the value for that user has been updated, if it hasn't it need it to insert a new record in the database...I also should mention that the 'every X hours' can change per user too, and the total runtime of the function per user can also vary.
So basically I need a function that runs continuously on the server for few hours per user. What is the best way to do this? I want the site to be able to support many users (like 10000 +).
I'm willing to try new technologies for every aspect of the site, I'm still in the design phase and I was looking for some input.
I've looked at cron but not really sure how well it would work when dealing with so many users...
edit: Here is a typical scenario of events;
User presses button on the website and closes the browser.
Server starts a timer from when they pressed the button, now
the server will check if that user has pressed a different button within a given time frame (time frame can change per user), say within 30 minutes. If they didn't press the other button then the server needs to automatically insert a new record in the database.
The script will need to continue running, checking every 30 mins for say the next 5 hours.
Thank you!
Cron would work as well as you can code the page it will run. It's not a cron limitation.
The question is ambiguous btw. Maybe explaining your full scenario would help.
Meanwhile, my suggestion would be to set up a scrip that allows you to manually check what you need to check.
You definitely need the DB to be InnoDB optimized with proper indexes to be able to support 1000 plus users.
To alleviate the number of calls to the database, a common practice is to run scripts only on what you are interested (so in the case of users you would only select those who have logged on in say the past 3 hours)
That's achievable in 2 ways, a simple select statement, or by adding entries to a specific table on the login page, and remove them after the automated script has finished running.
All of this is pure theory without understanding exactly what you need to do though.
You are telling what/how you want to do, but not why you want to do it. Maybe letting us know why could lead to a different how ;)
However, what you can do is still use cron (or anything similar). The trick is to have
a last_interaction timestamp column
a maximum_interval column
a daily_runtime column
in your users database. Not optimized but you are in the design phase so you shouldn't pay too much attention to the performance aspect (except is explicitly required).

PHP: how to update user logged in timer without using AJAX calls

I am creating a web application named Online Exam using PHP+MySQL and AngularJS. Now I am getting some trouble on project like changing the user looged in status. Let us take this condition as a example:
Suppose a authorized user/student successfully logged in online exam section(After successfully logged current time will be inserted in the db in exam_start_time column as unix timestamp format and exam_status will be set as 'ACTIVE`.
1hr(60 min) countdown timer is initialize for him/her as per the inserted exam_start_time in db.
Now suppose after 15 min the system shuts down automatically, then if user logged in again(In same system or other) then the countdown timer should be set for 45 minutes only.
Previously I was updating the last_activity_time in our table in every 10 sec(using ajax calls). but now I want to change this way, Is there any way like(socket or network programming using PHP) to update the column.
Here is my table structure which is managing user logged in status
Please give me some suggestions on it.
A Php socket server programming tutorial : http://www.christophh.net/2012/07/24/php-socket-programming/
Sockets, as Pascal Le Merrer mentioned, is IMO your best option. But beware of Apache! Every WebSocket holds one Apache thread, and Apache wasn't designed to do that. when too many (and by too many I mean few dozen) clients connect to your site, it will crash. (I've been there while trying to implement long polling/comet, ended up using NodeJS. If you're using nginx, it is more likely that it will become low on resources and effective, but there are also other ways. Take a look here:
Using WebSocket on Apache server
If you find this uncomfortable/hard to learn, try also another idea:
try to add hidden iFrame to your exam page, pointing to prepared site that updates database row. Use javascript to refresh this page every 10-15 seconds. Every refresh causes update of specific row in DB, using current date and time. It should work (not tested, but give it a try).

Time tracking like Expert rating tests

I am trying to create an Online Quiz script like expert rating test on ODesk or Elance.
I want to track the time, means how much time have passed and left. I also want to stop the time counter, if the user internet connection is disconnected, so that he can start from where it was disconnected.
One last thing how to disable the last questions, which were attempted by the user. I am using PHP, MySql for it.
Your ideas will be great help for me.
Thanks in Advance
I've done something like this. Basically you have the right starting idea. Create a timer table which stores start times, test id and user id.
On each page load or AJax call you check the current timestamp minus the start time to see how long has gone since they started. If at any point it passes your limit you redirect them to the test complete page. Don't worry about the internet connection its actually irrelevant. This basic rule covers all.
I've done something related to this. you have to think about this to begin the idea. Create a timetable that stores begin the time, user id, or testing id.

Categories