I am currently working on a Javascript multiplayer game.
When users want to play, they enter a waiting room where they wait for players to play with.
It is stored in a SQL database this way :
I have a table named USER with some data on the players, and another table named WAITINGROOM which associates the id USERID of the user waiting for a game with other infos.
When players leave the waiting room or close their browser, I delete the row with their id in table WAITINGROOM.
But let's suppose the user loses his internet connection while looking for a game. How can I know he is offline so I can remove the row containing his id ?
The player is offline so it is definitely not client side I can deal with this.
Maybe server side in PHP ? Or directly in the database using timeouts or something...
I assume you have a script (probably called via ajax) which fetches the online users for the current user. Simply add a column like 'last_seen_online' with a timestamp. Update the field every time the user calls this script. Now you can filter it in your sql for example get all users which have been online during the last minute. - Everything not active since one minute is considered offline like this.
To get rid of users which went offline you can implement a garbage collection(like php with sessions does). You grab all users which havent been seen since the last (for example)5 minutes. You place this garbage collection in the same script. To keep the load low. You dont call it every time, just like 50% of the time with if(rand(1,100) > 50) or any percentage you like.
Related
I have a script that is written in PHP. It uses MySQL database to store records.
Basically, I have team of users that are making random calls to a different business. I want to add list of phone number in a queue "pool table". The system will need to assign the new call to the user. Now If a user is already working on a phone call I don't want another user to start calling the same number. I need a solution to prevent 2 people having the same record assigned to them. So if phone number 000-000-0000 is assigned to the user X the same record will be skipped and the next one in line get assigned to the next available user.
This table will be accessed a lot so I need a good solution that will prevent 2 people from working on the same record and also not cause system issues.
One way I can think of but looking for a better solution is
open transaction
select a call where record status is available
update that call by changing the status from records available to record pending.
commit transaction.
If the use completed the call then updated with a status of completed otherwise make the record available again.
what are other solution available for me?
Thanks
Without a little more information about the workflow, it's hard to know what to suggest, but it sounds like users are interacting with the application somehow while they are taking calls...true??
If so, you must have some way for the user to alert the system they are ready for a call.
ie...
I just started my shift... Deal me a number.
Or...
Submit notes from last call... click submit and Deal me another number.
In this scenario, it seems like it should pretty easy to just let the users "request" the next number. You could probably just insert the users id on that record so it shows in their queue.
I'll try to explain my question the best way I can.
I'm not asking for codes, only for the best method of doing it.
I want to create a browser game and use time for upgrading stuff, building etc.
For example, to build 1 house will take 1 hour.
So I will began with saving the timestamp+(60*60) at the moment the user did his action.
My question is, how to update it the best way?
One way I thought of was to add function that check every page view of the user if it's done.
But then if he's not logged in the update wont happen.
Second way i thought about is for every page view of any user to check for every user registered. But it's not effective and there is a problem if no user is logged in.
Any suggestions?
I had my game doing it simply, without crons.
When a player wanted something that takes time, i just updated his database information with the appropriate time of ending that job (columns are just examples)
UPDATE player SET jobend = UNIX_TIMESTAMP() + (60*60*4) # ending in 4 hours
Then, every page that had an information about the remaining time, i just used something like this:
SELECT (jobend - UNIX_TIMESTAMP()) AS jobremaining FROM player
I formatted correctly the time using strftime and i displayed that to the user.
In the case the remaining time was negative, the job was done.
There was no-need for absolute counting since user was able to do something with the job when he was connected.
When the player just changed pages or doing something else i had a function where i just checked all timely events while the user was online (so to catch any negative timer), then presented with javascript any change (i posted javascript counters for every page)
Now, if you talk about updating in real-time, cron is the way but are you sure you're going to need it for a game? I asked that question myself too and the answer was not.
EDIT
If another player sees the buildings on schedule page (an hypothetical page) i am doing the same calculations; if a time just got negative for a specific player (regardless if another player see the page), i just reward him with the building (in database i make all the changes), even if he's offline. There's no harm in this, since he can't do anything anyway. The other players will just see he has a building. The key here is that i execute the required updating PHP code regardless of player's connection to the game; as long at least ONE player is logged-in i'm executing the progress function for everything.
This isn't so slow as it sounds (updating all players by using just a connected player that visits a specific page). You just have a table of 'jobs' and check timers against the current time. More like a single query of getting the negative ones.
I have an Ajax which sends username/id to PHP every second in order to know which user is currently online.
PHP then takes the user id and updates it's field in an activity table with the current time for the given user.
Is this approach correct, because it uses a lot of CPU from my current hosting plan (and that's just for one session)?
Instead of continuously sending data to the server, update the activity for a given user upon navigation. This approach comes with advantages.
It will be gentle on system resources
It will be easy for you to track whether a user is active or not
I know the title is complicated, but i was looking for some advise on this and found nothing.
Just want to ask if i'm thinking the right way.
I need to make a top facebook shared page with about 10 items or so for my website items (images, articles etc.)
And this is simple, i will just get the share count from facebook graph api and update in database, i don't want to make it in some ajax call based on fb share, it could be misused.
Every item has datetime of last update, create date and likes fields in database.
I will also need to make top shared url in 24h, 7 days and month so the idea is simple:
User views an item, every 10 minutes the shared count is obtained from fb graph api for this url and updated in database, database also stores last update time.
Every time user is viewing the item, the site checks last update datetime, if it is more than 10 minutes it makes fb api call and updates. It is every 10 minutes to lower fb api calls.
This basically works, but there is a problem - concurrency.
When the item is selected then in php i check if last update was 10 minutes ago or more, and only then i make a call to fb api and then update the share count (if bigger than current) and rest of data, because a remote call is costly and to lower fb api usage.
So, till users view items, they are updated, but the update is depending on select and i can't make it in one SQL statement because of time check and the remote call, so one user can enter and then another, both after 10 minutes and then there is a chance it will call fb api many times, and update many times, the more users, the more calls and updates and THIS IS NOT GOOD.
Any advise how to fix this? I'm doing it right? Maybe there is a better way?
You can either decouple the api check from user interaction completely and have a separate scheduled process collect the facebook data every 10 minutes, regardless of users
Or, if you'd rather pursue this event-driven model, then you need to look at using a 'mutex'. Basically, set a flag somewhere (in a file, or a database, etc) which indicates that a checking process is currently running, and not to run another one.
I wonder if this is a good solution for a medium size social site. Its about managing online/offline indications of users. My solution is to include a script on each page that first of all updates the "last activity" field of the current user with a timestamp, then i select all users that havent been active within the session expire time(but is still online accordingly to the table) and sets the online flag(in db) to false. Is this a solution that is commonly used or will the sever load be to much when a bigger amount of users are navigating throug the site? Is there any better solution? Be aware that im not only intrested in the amount of online users but also names, therefore a session based script seems to complicated and inaccurate.
Thanks in advance!
It is good enough but better you could store this information in activity table: for any active user insert/update a row with his user_id and for inactive for more than N minutes one - remove rows.
A table that stored sessions should contain a field called "LAST_ACTIVITY_DATE", TIMESTAMP. So whenever they load a new page or you update something with AJAX, just update LAST_ACTIVITY_DATE with current_timestamp.
Then when you need to get online users, get those who have last_activity_date within 5 minutes from Current_timestamp.
Easy as!