Refreshing content automatically when new tuple is added to the DB - php

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).

Related

adding websockets to existing php application

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?).

How to avoid some SQL queries in PHP?

I am developing a PHP web app with jQuery and Twitter Bootstrap. And it uses AJAX for everything. So, I show a form in HTML5, the user press a button (class="btn"), the form is sent to PHP (jQuery, AJAX), PHP makes a query to the MySQL and echoes an answer, which is shown in the form (jQuery). This is basically how the web app works.
But here's the deal, the first form it is showed, it's a div that shows some news. For example:
A new user was created.
There is new important date.
Someone wants to text you.
So I've created a table in MySQL called News where I saved some values than mean something like:
1: A new user was created
...
Everytime the user log in will se that. It means that there will be a query and a response as soon as the HTML5 get loaded when a user log in.
The index.html file has a navbar (Bootstrap), and a option call News. When the user clicks it, the same query will be executed, but not necessarily the same response.
I thought in modifying the div with news whenever the user does an action. But, an action can also be done by another user. So it is necessary to make the query again!
Is there any solution that allows me to avoid querying the database when the user wants to get the news? Or how can I know that it is necessary to update the div right now? I was taking a look at caching queries but didn't arrive to a conclution.
Sorry if my english is not too good, it is not my native language.
Thank you.
You can send a timestamp in every news response from the server and save it in javascript. The next time you make a request, send the timestamp you saved and the server checks if there are more recent news, sending nothing if there is none as the last response is still the newest.
Well, there is a downside here, you still need to make a query to the database (filtring the results with a WHERE clause like 'WHERE ... TIMESTAMP > last_timestamp_from_browser') which is perfectly valid, SGBDs are designed for this, and if you don't have thousands of users accessing your website at the same time there will not be any problem. With this approach you will only save bandwitdh as the connection to the database is still made.
There is another way that prevents this connection from being made, cache some values of last news inserted which could be user specific or global and save them in APC module (or memcached). You'll need to discover what to cache and when (you can't cache the entire database, just some well organized timestamps and maybe the most requested news for example). This way you prevent the database connection from being made. This will force you to do many many more code, so, use it only if you really need it, like thousands of user connections at once.

how to use ajax auto refresh effectively?

I am looking to have an auto refresh a la Facebook homepage. I have already implemented the Ajax code but I am wondering what is the best way to go about the refresh.
I can do a setInterval and have it refresh every X minutes, but this seems unnecessary when the site is open in a tab, but not in use.
I can bind it to an event like mouseover (which i tested) but then it refreshes every time the mouse moves over the div, and for the most part is unnecessary. (as well as creating a heavy load on the server.)
I suppose ideal situation would be when there is a mouseover, it checks how long ago it was last updated, and if its been more than X minutes, do a refresh. Which I suppose is a combination of both the above methods.
Is there a way I don't know about? What about some kind of method that is implemented on the page where my div content comes from (my own page located on the same server), that waits for new material then "pushes" it to my div, instead of of my div going and "pulling" the info from the page?
Facebook does it using a keep-alive connection.
This means, an ajax request is sent to the server with a Keep-Alive header. It will stay alive until new content is available, the server then returns the response and the connection closes. As soon as this happens, a new keep-alive connection will be established etc.
On the PHP side, you can use sleep() in combination with an endless loop to check for new conent.
However, I don't know how much this affects your server's cpu usage...

Page refresh on record in database changing

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.

cache or not to cache

I have an ajax application where the client might lookup bunch of data frequently(say by key stroke), the data gets updated on the server side once or twice a day at fixed times by a demon process. To avoid visiting the server frequently, I store the data in a xml file, so the client downloads it once when the page first loads, then look the data up from local data file via javascript.
But the user might load the page shortly before the changes, then start using it without ever refreshing the page, so the data file never gets updated, hence keep telling user the new data is not available.
How do I solve this issue?
You should set the appropriate HTTP cache headers for that generated XML file so any client request past that time will get the new version and cache it locally, like any other static content.
If the data load is not very large... Include the data in the main document as an XML island. Either form it in document generation (aspx, php, whatever) or fill in (via ajax calls) a reserved document node upon loading. This way, your user always has the latest data, you do not have to worry about caching, and life is much simpler.
If it is large, fill in that node as needed via ajax calls.
One obvious option is to add some AJAX that polls the server every x minutes. If the data needs refreshing just show a non-blocking message somewhere obvious on the page notifying the user that fresh data is available and provide a link to refresh the page. As an extra you might want to provide a button for the user to click if they want to check for fresh data (rather than waiting for x minutes to elapse) themselves.
If you use a HEAD request you can just check the last-modified header.
You said that the update time is FIXED? So when the user visit your page SHORTLY before the update time to come, you can set a javascript variable to you page that indicate how many minutes, for example, until the next update, and run a client-side timer such as:
timer = {
run: function() {
if( now + minuteToUpdate > updateTime - startVisitTime ) {
// make ajax request here to update XML file
}
},
interval: //you can determine this since this will run in client-side
}
Do not you POLLING in this stiuation because it's waste and stressed to call server every time.
You can set some SESSION variable to help this run better and more exactly
Justin
What runtime said...
Or, since update times are fixed and infrequent, then when you serve your XML, also include a cache expiration time as an element or custom header. This way, if your user visits the site 1 minute before the XML update, you can code your client to expire its cache and update itself on the next request made after that 1 minute mark.

Categories