Visualizzazione risultati 1 fino 9 di 9

Discussione: Problema refresh chat e utenti online con long polling

  1. #1
    sneh non è connesso Neofita
    Data registrazione
    22-03-2015
    Messaggi
    8

    Predefinito Problema refresh chat e utenti online con long polling

    Sto cercando di creare una sorta di chattina in long polling, però il CloadFlare un pò mi da problemi per tutte le chiamate che fa: per tanto vi vorrei chiedere se i miei codici sono da ottimizzare, vi passo le due funzioni dove faccio le richieste più pesanti: Online() (aggiorna gli utenti online) e Euphoria() (aggiorna la chat con un nuovo messaggio)

    CLIENT:
    script client che fa richieste longPolling json al file requests.php:
    ###PS: ho oscurato le funzioni cun cui creo gli elementi nel doom, perché futili al problema
    Codice PHP:
        <script>
            function Online(content){
                var data = null;
                if(content == null) data = {<?=REQUEST_TYPE?>:'getPollOnline'};
                else data = {<?=REQUEST_TYPE?>:'getPollOnline','content' : content};
                $.ajax({
                    url:"requests",
                    method:"post",
                    dataType:"json",
                    data:data,
                    success:function(data){

                            makeOnlineList(data["users"]); //aggiorna gli utenti online
                            online_update++;
                            Online(data);
                    },
                    error:function(){
                        return;
                    }
                });
            }
            function Euphoria(id){
                var data = null;
                if(id == null) data = {<?=REQUEST_TYPE?>:'getPoll'};
                else data = {<?=REQUEST_TYPE?>:'getPoll','id' : id};
                $.ajax({
                    url:"requests",
                    method:"post",
                    dataType:"json",
                    data:data,
                    success:function(data){
                            addNewMessage(data,false); //aggiunge il nuovo messaggio ala chat
                            last_update++;
                            Euphoria(data.id);
                    },
                    error:function(){
                        return;
                    }
                });
            }
            

            //variabili per accendere o no delle funzioni nel setInterval sotto
            var current_update,current_online_update = 0;
            var last_update,online_update = 0;
        jQuery(function($) {

                //EuphoriaAll(null,true);  //questa funzione è per mostrare tutti i messaggi all'inizio però non è completa
                Euphoria(); //questa funzione se comprendo che il database è cambiato, aggiorno la chat
                Online();  //stessa roba per la chat ma  per gli utenti online

                //questo setInterval gira ogni minuto e riaccende una data funzione nel caso il server non fosse più attivo
                setInterval(function(){
                    if(last_update > current_update && $.active > 0){
                        current = last_update;
                        Euphoria();
                        //Online();
                    }
                    else if(online_update > current_online_update && $.active > 0){
                        //    Euphoria();
                        Online();
                    }
                },60000);

                //qua mostro solo se uno sta digitando o no
                //al keydown aziona, nel keyup se si sta digitando toglie la digitazione dopo 2s, al blur leva la digitazione
                var on_digits = false;
                $("#message").keydown(function(){
                    toggleDigits("visible");
                    on_digits = true;
                }).keyup(function(){
                    if(on_digits){
                        setTimeout(function(){
                            toggleDigits("none");
                        },2000);

                    }
                }).blur(function(){
                    toggleDigits("none");
                    on_digits = false;
                });


                //sulla testarea invio i dati al form dopo aver premuto  enter
                $("#message").keydown(function(e){
                    if(e.keyCode === 13){
                        if(e.shiftKey) return;
                        else {
                            $("form[data='chat']").submit();
                        }
                    }
                });
                $("form[data='chat']").submit(function(e){
                    e.preventDefault();
                    var data = $(this).serialize();
                    data+="&<?=REQUEST_TYPE?>=putMessage";
                    $.post("requests",data,function(e){
                    });
                    $("#message").val("").get(0).setSelectionRange(0,0);
                setTimeout(function () { $("#message").val(null); }, 20);
                });

            });
            </script>
    File requests delle due richieste:

    Codice PHP:
      case "getPollOnline"#aggiorna gli online
              
    header("Content-Type: application/json");
              
    set_time_limit(0);
              while (
    true) {
                  
    $last_request_content = isset($_REQUEST['content']) ? (object)$_REQUEST['content'] : null;
                  
    clearstatcache();
                  
    $last_list ONLINE::getList(time());
                  
    //last_list è un oggetto vario contenente anche un array "hash" e calcolo la diversità con quello              
                  
    if ($last_request_content == null || $last_list["hash"] !==  $last_request_content->hash ) {
                      
    #CONF::json(...) == json_encode(...)
                      
    echo CONF::json($last_list); #qui cedo a client il json della mia lsta
                      
    break;
                  } else {
                      
    sleep(1);
                      continue;
                  }
              }
              break;
              case 
    "getPoll"#aggiorna la chat con un nuovo messaggio
              
    header("Content-Type: application/json");
              
    set_time_limit(0);
              while (
    true) {
                  
    $last_request_id = isset($_REQUEST['id']) ? (int)$_REQUEST['id'] : null;
                  
    clearstatcache();
                  
    $last_message CHAT::getLast();
                  if (
    $last_request_id == null || $last_message->id $last_request_id) {
                      echo 
    CONF::json($last_message);
                      break;
                  } else {
                      
    sleep(1);
                      continue;
                  }
              }
              break; 
    Ultima modifica di sneh : 24-03-2018 alle ore 18.42.06

  2. #2
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,667

    Predefinito

    Il codice JavaScript è un po' lungo per esaminarlo tutto su due piedi.
    Quello che ho notato a colpo d'occhio è questo frammento:
    Codice:
    function Online(content){
      ...
      $.ajax({
        ...
        success: function(data) {
            ...
            Online(data);
        },
        ...
      });
    Ovvero il fatto che la funzioneOnline (così come Euphoria) chiama ricorsivamente ed immediatamente se stessa ogni volta che la chiamata Ajax ha successo.
    In pratica la rete è costantemente occupata da chiamate Ajax, appena ne termina una con successo ne parte un'altra, in questo modo tieni aggiornati tutti i client con il minor ritardo possibile.
    Non credo che per una chat avere dei tempi di risposta così brevi sia necessario, e se questo ti crea problemi con la quantità di richieste suggerirei di inserire una pausa tra un aggiornamento e l'altro, ad esempio con
    Codice:
    setTimeout(Online, 500);

  3. #3
    sneh non è connesso Neofita
    Data registrazione
    22-03-2015
    Messaggi
    8

    Predefinito

    Una cosa brutta è che dopo tot di tempo se il server non risponde più, non ricarica più le funzioni euphoria e online
    per tanto ho scritto questi codici :
    Codice PHP:
        setInterval(function(){
                    if(
    last_update current_update && $.active 0){
                        
    current last_update;
                        
    Euphoria();
                        
    Online();
                    }
                    else if(
    online_update current_online_update && $.active 0){
                        
    Euphoria();
                        
    Online();
                    }
                },
    60000); 
    in caso di assenza dela risposta del server, dopo un minuto le riaccendo se non ci sono poling, questa cosa del $.active in realtà non credo di averla pensata bene

    infatti capita che non ricarichi le cose al cambiamento del database che leggo nella parte php

  4. #4
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,667

    Predefinito

    Ho guardato anche il codice PHP. Ci sono alcuni problemi di fondo:
    Codice PHP:
    switch (...) {
      case 
    "getPollOnline":
        
    set_time_limit(0);
        ...
        while (
    true) {
          ...
          if (...)
            break
          else
            continue
        }
        break;

    Dubito che set_time_limit(0) abbia effetto in un server condiviso: se potesse avere effetto e tutti lo usassero, il server collasserebbe.

    Questo automaticamente rende inutile l'uso del while(true) e di questa struttura del codice, e spiega perché dopo un po' il server non risponde più: raggiunge il timeout.

    Capisco che quei while (true) abbiano lo scopo di mettere in attesa server e client finché i dati aggiornati sono disponibili, ma con PHP su un web server questa non è una strada percorribile.
    Il metodo più pratico è quello descritto in How do I implement basic “Long Polling”?, il "problema" è che non è più un vero long polling.

    Anche nella discussione su Stack Overflow suggeriscono di usare strumenti diversi da PHP per lo stesso motivo.

  5. #5
    sneh non è connesso Neofita
    Data registrazione
    22-03-2015
    Messaggi
    8

    Predefinito

    Sta di fatto che io voglio usare Altervista, anche io per una chat di messagistica userei websockets in nodejs o rachet per dirci, ma io voglio fare questa cosa qui su Altervista e se col php non potrò far molto, mi baserò su degli eventi specifici in javascript per ricaricare i messaggi richiedendo comunque delle richieste ajax al server. Altro non so, se si può fare qua di messaggistico su Altervista , oltre ai metodi quelli che sto usando, non ne conosco.

    Secondo il tuo consiglio ho levato lo set_time_limit(0)
    Ultima modifica di sneh : 26-03-2018 alle ore 12.42.46

  6. #6
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,667

    Predefinito

    Messaggistica su AlterVista con PHP + JavaScript si può ottenere, ma non con il (vero) long polling.
    Con il polling "semplice" non dovresti avere problemi.

  7. #7
    sneh non è connesso Neofita
    Data registrazione
    22-03-2015
    Messaggi
    8

    Predefinito

    long polling semplice? intendi leggere ogni tot di tempo il server?

  8. #8
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,667

    Predefinito

    Sì, il classico, orribile, inefficiente polling
    Che io sappia, in ambito web è l'unica vera alternativa.

  9. #9
    sneh non è connesso Neofita
    Data registrazione
    22-03-2015
    Messaggi
    8

    Predefinito

    Che cosa brutta

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •