Okay so I'm running into a small problem.
Basicly my whole website runs through the AJAX system, content is loaded in the middle page, and theres a left and right menu which dont refresh.
Currently I'm trying to look for a PHP->Ajax feature that refreshes the whole website incase a certain record changes in the MYSQL table
Okay so every user has a record called "State" which indicates the state of their account, this can be changed by anyone, for example the account gets shot and killed by someone. How do I make it so it checks what state you have and if it changes from the "standart" state that it performs a full page refresh.
I tried to find an answer for this everywhere but haven't been able to figure something out.
-----Edit-----
Okay so I'll also notify, I kind of know how to perform a full page refresh, and I know how to retrieve data from the mysql database, this isn't the problem.
I have a table with all the users accounts in it, one of the records for every user is called "State" everybodies state will be 1 which means alive. when its 0 it means its a dead account.
On a part of my website theres an auto refresh with always fetches data from the database every 5 seconds, to check if your online if you have money etc. it also checks what state you have.
the only thing I want to do, is that when it sees your state is 0, it performs a full page refresh, considering state 0 means death, you should be seeing a deathscreen, I want it to perform a full page refresh cause the menu's have to dissapear. and it has to redirect you to the deathpage.
You need long pooling / comet - basically you keep open connection between the client and the server, and when the state is changed, the server sends the response to the client.
Basically, you'll open a long pooling connection, sending the userid.
The server script receives the userid, and starts monitoring for changes for that user. If such change is detected, send the response.
If performance is concern, you can use Tornado web server. What's nice about it, is that you can post from another application to the web server, and it can detect which client is affected by the change and send response to that client.
Related
I am currently creating a stock market simulation and am working on the moment that the user logs into the simulation. I have a PHP script that will generate a certain price for a company four times and update it into my MySQL database while running. I currently have the following code:
PHP:
if (isset($_SESSION['userId']))
{
$isPlaying = 0;
while ($isPlaying <= 3)
{
$priceTemp = (rand(3300, 3700) / 100);
$sql = "UPDATE pricestemp SET price = $priceTemp WHERE companyName = 'Bawden';";
mysqli_query($conn, $sql);
sleep(1);
$isPlaying++;
}
echo '<h1>Welcome to the simulation</h1>';
}
I am aiming for these updates to happen in the background once the user has logged into the simulation. When refreshing my database every second, the updated prices are shown which is one of my objectives. However, what I would like it to do is still load the HTML onto the page (to say "Welcome to the simulation") while updating the database with every second with an updated price.
So far, when I log in, I have to wait 4 seconds before the HTML will load. In the future, I hope to have it consisently updating until a certain condition is met but when I have set an infinite loop earlier the HTML never loaded.
What do I have to do to allow the HTML to load once logged in and have the prices being generated and updated in the MySQL database in the background with no delay in either of these tasks happening?
You have a fundamental misunderstanding of how web-based requests work.
What you need to understand is that PHP is a server-side language. PHP generates any combination of HTML, CSS, JavaScript, JSON, or any other forms of data you want and sends it to your web browser when it's finished. While it's doing that, it can also manage data within a database or perform any other number of actions, but it will never send what the web browser can make use of until it finishes setting everything up. So if you're within an infinite loop, it will never finish and therefore nothing will be sent back to the web browser.
To remedy this, you need to use something called "asynchronous JavaScript", more commonly referred to as "ajax". Specifically, you first send some initial HTML to the web browser in one request and let the request end immediately. This allows the user to see something without waiting around for an indefinite period of time. Then, on the web browser end, you can use JavaScript to automatically send a second request to the server. During this second request to the server, you can perform your data processing and send back some data when you're finished to display to the user.
If you want to periodically update what you show the user, then you would repeat that second request to refresh what is shown on the user's webpage.
Any time you see some kind of "real-time" updating on a website, it's not coming from a single, persistently open connection to the web server--it's actually a series of repeated, broken up requests that periodically refresh what you see.
Broken down, standard web request workflows look something like this:
Web browser asks the web server for the webpage. Web browser waits for a reply.
Web server generates the webpage and sends the webpage to the web browser. Web server is done.
Web browser receives the webpage and shows it to the user. Web browser stops waiting for a reply.
Web browser runs any JavaScript it needs to run and requests data from the web server. Web browsers waits for a reply.
Web server processes the request and sends the requested data back to the web browser. Web server is done.
Web browser receives the requested data and updates the HTML on the webpage so the user can see it. Web browser stops waiting for a reply.
As you can see, each series of requests is 1) initiated by the web browser, 2) processed by the web server, and 3) any replies from the web server are then handled by the web browser after the web server is finished up. So each and every request goes browser -> server -> browser. If we add steps 7., 8., and 9. to the above, we will see them repeat the exact same pattern.
If you want to avoid adding JavaScript into the mix, preferring to refresh the entire page every time, then keep your data processing short. Optimize your database calls, fix your infrastructure (make sure your server and database have a LAN connection, that your hardware is good enough, etc.), make your code more efficient... do whatever you need to do to keep the processing time to a minimum.
This is all incredibly simplified and not 100% accurate, but should hopefully help you with your specific problem. The short version of all of this is: you can't show your HTML and process your data at the same time the way you're doing things now. You need to fundamentally change your workflow.
You have to do this in 2 network calls. The first network call should fetch the html. Then you have to use Javascript to fire another call to update your data. Once that api call returns it will update the html.
The scheduling model to manage the frequency of a background operation based on the frequency of requests at the front end is a very difficult problem. It's also a problem you don't need to solve. The data doesn't need to be changed when nobody is looking at it. You just need to store when the data was last looked at and apply greater deltas to older data.
I have an php framework which supports me building websites and allows me to edit the content directly in the frontend via inline editing. I have kind of an api, which receives the updates via an ajax call.
So far i was the only one using it, but in the future there could me more people editing the pages the same time, so the page has to be locked for other users the moment someone starts editing (maybe displaying which people are viewing the page at the moment as well).
I have some experience in php, javascript and a rough understanding of http requests, node.js and so on, but I am not an expert.
Now I would think, that i simply had to setup up a websocket server, tell the websocket server, when a user is viewing and editing a single page and update the page for the other clients and lock the editing buttons via javascript. So the Page would be only marked as locked on the websocket server.
Maybe I could check the status of the page when updating the content of a page by sending another request to the websocket server, if the page is locked. Or should i update the database directly through the websocketserver and mark the page as locked in the database?
Can you tell me if I'am on the right track or if it's a completely wrong approach?
PS: Even if it may be an overkill I still would want to try it only to practice, as I haven't used this technology so far :)
The approach that I would take is as follows:
Problem: (restating to show my understanding)
Notify clients when content is being edited to prevent conflicts.
Hard requirements:
Implemented using WebSockets -- for educational purposes.
Assumptions:
Sending the edited content will continue to be done via AJAX calls.
Clients do not need to know about content on pages that they're not currently viewing.
Clients should learn about the lock status of content once the page is loaded, before (or at least as soon as) the ability to edit content is available to the user.
It may become a requirement for all clients to be notified that contents on a page has been updated so that they can request an updated version through AJAX calls.
Multiple pieces of content may potentially be edited on a page, and locks should only apply on a per-content chunk basis, not a per-page basis. (I.e., a page that lists 10 customer addresses, if editing 1 address, let the other 9 be available for others to edit.)
Approach:
Personally, I'd use a PHP-based WebSockets server, but that's because I'm biased towards the one I wrote. Because of that, I'm going to approach this answer from a PHP-WebSockets perspective, and I apologize for any server specific implementation details that might not translate. That being said, it is far more important for you to use the tools that you're most comfortable with than to use a tool that I recommend, and I am trying to write in as general terms as possible.
Client JS:
On connecting, send the URL of the page that is loaded.
On initiating and completing (committing or aborting) edits, send a message indicating which bit of content on that page to lock/unlock.
Client may request the lock status of any bit of content at any time.
WebSockets Server:
On new connection, store the URL that they're on. (The same user can have multiple pages open in multiple browser tabs, but the client's page to socket relationship should always be 1-to-1.) If the page has content that is locked, send that connection a message saying which is locked.
On a new lock, store the URL, client, and which piece of content is being locked. Send a message to all clients who are registered to that URL (including the originator, who will use that reply as confirmation) on what content is now locked. If desired, store the lock status in the DB.
On removing a lock, remove the record for the URL, client, and which piece of content was locked, sending a message to all clients registered to the URL, and clearing the flag from the DB. Leave room in this method to poll the database/framework on whether the content was changed or not, to potentially tell the clients registered to that URL to invalidate their view and fetch fresh content.
On a query about any locks, respond with all locks that currently exist for that page.
On client disconnect, remove any locks. If locks are removed, notify all clients registered to the URL. If the user re-connects, it will be on a separate socket so they'll have to establish a new, different lock anyways. Clean up the connection details as well (no need to try to send messages down a pipe that's closed, right?).
I'm at the conceptualizing stage of developing something but not quite sure of a certain feature.
I have a DIV in a form, lets call it id='divComments'. This div contains all of the comments on a particular title. It retrieves all of the data from the database which is easy to do.
Now when the page is refreshed, this div is populated with all of the comments. If another user adds a comment, all of the other users will see this comment when they log on (after that point in time) or if they refresh the page.
What if I want this div feeding from the database and refreshes automatically when something is inserted into the relation/table in the Database? so I have my page opened (im not refreshing it, just staring at it) showing lets say x and someone else adds a tuple in the particular database table lets call that y, and my div now shows x and y. In other words its updating real time from the database without refreshing.
Anyone has any idea how to go about doing something like this?
HTTP is stateless. Once an asset has finished downloading through a HTTP connection, the connection is destroyed and the server no longer has any knowledge of what the client is doing next.
There are ways of fudging stateful behaviour, using cookies and sessions and the like, but these still require a new connection to the server to fetch fresh data.
There are technologies in development that can allow a web server to "push" new data to the client the instant it becomes available (websockets, server-sent events, etc), but these are still at the draft stage for the most part and browser support is spotty at best.
The only real choice you have is polling the server with a refresh meta tag (EXTREMELY inefficient!), polling the server with AJAX (Better, in that you can design it to only fetch the data that's changed, but still not ideal), or using a long-lasting AJAX connection that remains idle until new data becomes available, at which point the data is downloaded, the connection is closed, and a new connection is opened to sit idle for more data (will allow immediate response, but difficult to set up properly).
I'm working on a project that involves multiple users and the ability to alter data.
Basically, when a user land on a page, he can enter information for a particular entry in a database. While he's on this page, no other user can access that particular entry. When he finishes, the entry becomes open again. Now, to restrict access to the entry is easy. I set it up so when the particular entry is selected, a value in the db states it is "Inactive" and no one else can get to that page. On the page itself, there's a "leave" and a "submit" button. Either of these will set the entry back to active.
The trouble I have is if the user decides to click on a different link, close the tab or somehow navigate away. How can I structure it to restore the entry back to an active state? I was looking into the "onunload" event and potentially using it to make an AJAX call. Is this the most logical route to take or is there something similar I'm missing due to my limited knowledge? Thanks for all your help.
I wouldn't go the onunload way (at least not exclusively), as it's not reliable in case of crash, power loss, etc. Chances are that entries could be locked "forever" in such case.
I'd embed an Ajax method in the page, which periodically requests a PHP script to "confirm" that the page is still alive.
You can use such "confirmation" requests to build/update a table to track current locks, working with s/t like a lock_id which uniquely identifies the "entry" being locked, session_id to uniquely identify the browser session holding that lock and expire_timestamp to set the time at which "entry" should be unlocked again in case no more "confirmation" requests of session_id come in and raise its expire_timestamp.
In combination with a cron job, periodically deleting records having exceeded their expire_timestamp, that should be a more reliably way to do what you are trying to achieve.
I worked on a similar problem and "onunload" is the right way to go. The down side of this is that if the browser crashed or is killed (from taskmanager), the unload does not get invoked. So it is better to have a job that sets entries to active state if it is sessionId corresponding to that entry is not present. (you can store a combination of sessionId & isactive lock to detect the browser idleness as well)
I have a buy.php page where user selects a product, enters some data like his name, address etc. Next he clicks on the "Buy" button to move to the Payment Gateway site for inputting his Credit Card no + CVV no etc. And at this point, without clicking on the 'Pay' button on this page, he closes the browser or his Computer gets switched off. This Transation ID is saved in Session.
How to track this situation and save it as "User Aborted" against his transaction ID in the Database in PHP?
The way we dealt with this issue was to keep the status of the transaction in the database as "incomplete" (or "aborted" in your case) from the beginning. When the payment is completed, the transaction status is changed to "completed".
You can't handle browser events (which is client-side) via php (server-side)
Use jQuery function .unload() which is supposed to be triggered on browser window closing
Documentation: http://api.jquery.com/unload/
Note: Nothing can take care about situation when Client Computer goes power-off instantly (not using Start > Switch Off or similar OS feature)
Note 2: Nothing in webpage can take care about crashed or killed browser
While you can potentially utilize Javascript to capture the browser's close event, unless you want to do something very quickly and aren't looking for any sort of feedback as to its success you might want to try a different approach.
From what you said above it would seem that you are trying to classify a given transaction as aborted, and you can do that simply by keeping track of different transaction stages in your database back-end. Have different stages for the given transaction and then set it to "aborted" if it was about to be processed and has been hung in that stage for a given amount of time.
Internally in PHP a connection status is maintained. There are 3
possible states:
0 - NORMAL
1 - ABORTED
2 - TIMEOUT
When a PHP script is running
normally the NORMAL state, is active. If the remote client disconnects
the ABORTED state flag is turned on. A remote client disconnect is
usually caused by the user hitting his STOP button. If the PHP-imposed
time limit (see set_time_limit()) is hit, the TIMEOUT state flag is
turned on.
This page will answer your question I guess.
Approach suggested by Aleks G is the best - however, as secondary measure, you may introduce some kind of 'heartbeats' between browser and server.
For example, issue AJAX requests over specified interval of time, letting server know that user is 'alive' (page is opened in his browser).
However, I repeat, this can be used only as secondary measure and you can't rely on it to set transaction status. There's no definite way to know whether user/browser is 'still there'.