Background information update

    Good day to all.

    Recently, I thought about the issue of background updating of information and one idea came to my mind.

    The essence of the task - we are on the news list page. You must update the list as new news arrives. PHP server language

    Let's consider the classic version through constant requests by ajax:
    1) The client sends an ajax request to the server, for example, at / ajax / get_upades & time = xxxxxx
    2) PHP looks for records in the database that are newer than time
    3) If there are any, select them and returns
    4) If there is nothing returns

    In this case, we are forced to constantly pull PHP and DB to answer the question, is there any new data?

    I really did not like this idea.

    I also didn’t like the options with long polling due to various implementation difficulties and keeping a large number of open connections.

    Then I decided not to shift the task of determining the availability of new data to the server itself, bypassing PHP completely

    The essence of the idea is as follows

    The client constantly pings an empty marker file. We will call it / ping / new_news.

    When the file is sent, the server sends a header - ETag of the form “10aa0f-7-4b877e2d4941c”. This is one of the headers involved in the caching mechanism. ETag is calculated based on inode, size and mtime file information. Those. when changing mtime (file modification time) the server will send another ETag.

    All we need is to update the mtime file, for example, touch () when inserting new news, but it’s better to create a trigger in the database to insert the record and change the file

    Next, we write a small class. Let's call it Updater

    var Updater = function(){
    	this.params = {
    		period: 		3000,
    		url: 			'',
    		onModified: 	function(data,x,modified){},
    		bgPause:  		false
    	};
    	this.interval = null;
    	this.ETag = '';
    	this.lastModified = '';
    	this.init = function(params){
    		var me = this;
    		this.params = $.extend(this.params, params);
    		if(this.params.bgPause){
    			$(window).blur(function(){ me.pause() });
    			$(window).focus(function(){ me.resume() });
    		}
    	};
    	this.start = function(){
    		var me = this;
    		this.interval = setInterval(function(){ me.doUpdate() }, this.params.period);
    	};
    	this.doUpdate = function(){
    		var me = this;
    		$.ajax(this.params.url, {
    			success: function(data,status,x){
    				if(me.ETag != x.getResponseHeader('ETag')){
    					me.params.onModified(data,x,me.lastModified);
    					me.lastModified = x.getResponseHeader('Last-Modified');
    				}
    				me.ETag = x.getResponseHeader('ETag');
    			},
    			beforeSend: function(x){
    				if(me.ETag != '') { x.setRequestHeader('If-None-Match', me.ETag); }
    			},
    			cache: false
    		});
    	};
    	this.pause = function(){
    		clearInterval(this.interval);
    		this.interval = null;
    	};
    	this.resume = function(){
    		if(this.interval != null) return;
    		this.start();
    	};
    };
    


    The script sends in a loop requests to the specified URL, when a Etag change is detected, onModified is called, the task of which is to send a request to receive the data itself.

    Sometimes Apache after changing the pinged file continues to give the old Last-Modified and ETag for some time. Adding the cache false parameter in an ajax request cures this situation.

    To reduce the number of requests, we stop pinging the server when the user does not see our page
    if(this.params.bgPause){
    	$(window).blur(function(){ me.pause() });
    	$(window).focus(function(){ me.resume() });
    }
    


    Here is such an idea came to mind. I will listen to your criticism, ideas, suggestions. Thank you all

    UPD. Added beforeSend parameter to ajax request

    Also popular now: