Long polling per verificare gli utenti on line

di il
2 risposte

Long polling per verificare gli utenti on line

Salve a tutti. Sono veramente disperato. Sono 4 giorni che ci sbatto la testa ma non riesco a venirne a capo. Non sapendo se il problema è dovuto lato client o server, provo a postare quì.

Questo lo script lato client:


jQuery( function(){
	if(jQuery.cookie('enable-chat')) {

	function user_longpolling(){
		var t;
				
		jQuery.ajax({
			url: 'php/chat/stream_users.php',
			type: 'GET',
			dataType: 'json',
			success: function( payload ){
				clearInterval( t );
				if( payload.status == 'results' || payload.status == 'no-results' ){
					t=setTimeout( function(){
						user_longpolling();
					}, 1000 );
					if( payload.status == 'results' ){
						jQuery.each( payload.data, function(i,msg){
						//jQuery( '.onlineusers ul li#u-'+  msg.id_user +'' ).removeClass('on');
						jQuery( 'li#u-'+  msg.id_user +'').addClass(msg.stato);
						});
					}
				} else if( payload.status == 'error' ){
					alert('Sono confuso, cortesemente ricarica la pagina!');
				}
			},
			error: function(){
				clearInterval( t );
				t=setTimeout( function(){
					user_longpolling();
				}, 15000 );
			}
		});
	}
	user_longpolling();

	}
});


e questo lato server:


<?php 
require_once('global.php');
require_once('../functions.php');
sec_session_start();

$id_user 	= $_SESSION['user_id'];
// crea connessione
$conn = mysqli_connect($hostname_alliance, $username_alliance, $password_alliance, $database_alliance);
// verifica connessione
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}

$time_wasted = 0;

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//verifico se l'utente è già nella tabella
$sql = "SELECT * FROM users_online where userid = ".$id_user."";
$result = $conn->query($sql);
	//se è stato già inserito aggiorno l'ora
	$time 		= time()+30;
	if ($result->num_rows > 0) {
			$sql = "UPDATE users_online SET timestamp = ".$time." WHERE userid = ".$id_user."";
	}else{
	//altrimenti lo inserisco nella tabella ed inserisco l'ora
			$sql = "INSERT INTO users_online (userid, timestamp)
			VALUES (".$id_user.", ".$time.")";
	}
//eseguo la query
$conn->query($sql); 

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

$old_users_check = mysql_query("SELECT * FROM users_online WHERE timestamp < ".time()." AND stato = 'on' AND userid <> ".$id_user." ORDER BY userid DESC");

$new_users_check = mysql_query("SELECT * FROM users_online WHERE timestamp >= ".time()." AND stato = 'off'  AND userid <> ".$id_user." ORDER BY userid DESC");

$num_rows_old = mysql_num_rows( $old_users_check );

$num_rows = mysql_num_rows( $new_users_check );
//se la prima query non mi da risultati
if( $num_rows <= 0 && $num_rows_old <= 0 ){
	//inizio il ciclo se non ottengo risultati
	while( $num_rows <= 0 && $num_rows_old <= 0 ){
		if( $num_rows <= 0 && $num_rows_old <= 0  ){
			// dopo 19 secondi invio una nuova richiesta
			if( $time_wasted >= 29 ){
				die( json_encode( array( 'status' => 'no-results' ) ) );
				exit;
			}
			sleep( 1 );
			$old_users_check = mysql_query("SELECT * FROM users_online WHERE timestamp < ".time()." AND stato = 'on' AND userid <> ".$id_user." ORDER BY userid DESC");
			$new_users_check = mysql_query("SELECT * FROM users_online WHERE timestamp >= ".time()." AND stato = 'off'  AND userid <> ".$id_user." ORDER BY userid DESC");
			$num_rows_old = mysql_num_rows( $old_users_check );
			$num_rows = mysql_num_rows( $new_users_check );
			
			$time_wasted += 1;
		}
	}
}

$new_user = array();

if( $num_rows_old >= 1):
while ( $row = mysql_fetch_array( $old_users_check, MYSQL_ASSOC ) ):
	$new_user[] = array( 
     'id_user' 	=> $row['userid'],
	 'stato'	=> $row['stato']
	);
endwhile;
mysql_query("UPDATE users_online SET stato = 'off ' WHERE timestamp < ".time()." AND stato = 'on' AND userid <> ".$id_user."");
endif;

if( $num_rows >= 1):
while ( $row = mysql_fetch_array( $new_users_check, MYSQL_ASSOC ) ):
	$new_user[] = array( 
     'id_user' 	=> $row['userid'],
	 'stato'	=> $row['stato']
	);
endwhile;
mysql_query("UPDATE users_online SET stato = 'on ' WHERE timestamp >= ".time()." AND stato = 'off' AND userid <> ".$id_user."");
endif;

mysql_free_result($old_users_check);
mysql_free_result($new_users_check);
die( json_encode( array( 'status' => 'results', 'data' => $new_user ) ) );


Le conseguenze sono drastiche. In effetti, verificando da console, alla prima richiesta inviata dal client, tutto procede regolarmente, ma appena parte la seconda chiamata, non mi permette più di interagire con il server fino all'ottenimento di una risposta. In sostanza, se invio un nuovo messaggio, rimane in sospeso finchè stream_users.php non esce dal ciclo. Non so se l'errore è causato dal client o dal server. Confido nel vostro aiuto

2 Risposte

  • Re: Long polling per verificare gli utenti on line

    Allora dunque, se il problema è che la chiamata ajax continua all'infinito allora dei impostare un timeout così puoi procedere con altre chiamate, ma se devi ricevere per forza un termine allora il problema è nel php
    ( più tardi analizzo il codice e spero di aiutarti intanto ragioniamo su queste ipotesi )
  • Re: Long polling per verificare gli utenti on line

    La dinamica dovrebbe essere questa:
    Faccio partire la richiesta ajax al server.
    il server esegue le 2 query iniziali. Se non trova records, inizia il ciclo while ripetendo le query ad un intervallo di 1 secondo. Il ciclo si dovrebbe fermare al 29esimo secondo ($time_wasted ) se non trova risultati. Se invece trova risultati esce dal ciclo e risponde con una array json.
    Dopo 29 secondi, se non trova risultati, o prima se li trova, fa partire una nuova richiesta da ajax ed il gioco riprende.
    Stò cercando di riprodurre una sorta di bacheca stile facebook. Questa tecnica la utilizzo per leggere i post e le rispote, con delle ovvie modifiche, e funziona alla perfezione.
    Il problema sorge con la seconda richiesta di utenti on line di ajax. In effetti accade questo. Trascorsi i primi 29 secondi, entro i quali non mi sembra ci siano anomalie, se provo ad inviare un post o una risposta, l'invio mi rimane in sospeso fino a quando stream_users.php termina il ciclo. In ogni caso ho provato anche a cambiare i tempi di stream_users.php. Ho provato a limitare $time_wasted a 2 ed aumentare i tempi di attesa prima del rilancio della richiesta ajax. Il risultato è stato quello che la pendenza ha aumentato ritmicamente i tempi di attesa... sono le 3 del mattino. Questa cosa mi stà togliendo il sonno nel vero senso della parola. Grazie per l'interessamento
Devi accedere o registrarti per scrivere nel forum
2 risposte