entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

Cómo actualizar página cuando exista un registro nuevo en BD

Buenas, tengo un panel en Yii Framework que muestra unos pedidos. Quiero que cuando un usuario realice un pedido y se almacene el registro en la BD la página detecte ese nuevo registro y se actualice automáticamente el navegador.
¿De qué forma puedo hacer eso?

Tengo esta función que me devuelve el número de pedidos:

public static function getPedidos() {
    $sql = " SELECT COUNT(*) as TOTAL FROM T_PEDIDOS WHERE ESTADO = 0 ";
    $connection = Yii::app()->db;
    $command=$connection->createCommand($sql);
    $rows = $command->queryrow();

    return $rows["TOTAL"];
}

1 Respuesta

1voto

white Puntos75880

Tienes la posibilidad de instalar nuevo software en tu servidor? podrías intentar con websockets, en node.js esta socket.io podrias enviar un evento desde el servidor con https://github.com/Wisembly/elephant.io

eso te ayudaría a que sea en tiempo real.

no puedes instalar node.js u otro software? podrías intentar con long polling o hacer una peticion cada x tiempo.

en donde cada x minutos hace una peticion via ajax al servidor y compruebas nuevos registros en la base de datos, esto se hace incluso en este sitio, si el trafico de tu sitio es grande entonces usar websockets podria ayudarte, si no, long polling o polling bastaría, cabe mencionar que long polling consume mucho mas, yo optaría por polling ( una peticion cada x tiempo )

var ultimo_registro = null;

function check_new_records()
{
    $.ajax({
        method: 'GET',
        url: '/pedidos',
        dataType: 'json',
        success: function(data)
        {
            if( data.ultimo_registro != ultimo_registro ) {
                // actualizar panel
                ultimo_registro = data.ultimo_registro
            }

            setTimeout(check_new_records, 1000);
        }
    });
}

0voto

danielreales7 comentado

Lo voy hacer con ajax, pero creo que no me está funcionando bien.
Tengo lo siguiente:

<script>
    var ultimo_registro = null;

    function check_new_records()
    {
        $.ajax({
            method: 'GET',
            url: 'http://www.xxxx.com/xxx/xx/refresh_page.php',//Esto devuelve el numero de pedidos
            dataType: 'json',
            success: function(data)
            {
                if( data.ultimo_registro != ultimo_registro ) {
                    // actualizar panel
                    location.reload();
                    playSound();
                    ultimo_registro = data.ultimo_registro
                }
                playSound();
                setTimeout(check_new_records, 100);
            }
        });
    }

    function playSound(){
        var mySound = new buzz.sound( "sound.mp3", {
            formats: [ "ogg", "mp3", "aac" ]
        });
        mySound.play();
    }
</script>

Que tengo mal que no me está funcionando?

0voto

danielreales7 comentado

Ahora he conseguido que me funcione pero me recarga la página a cada segundo.
Lo único que quiero es que realice peticiones AJAX al servidor y si fuera diferente recarga la página, pero nada.
Me sigue recargando la página a cada segundo no sé que estaré haciendo mal.

0voto

white comentado

la url http://www.xxxx.com/xxx/xx/refresh_page.php contiene un json valido? intenta que en refresh_page.php devuelva un json, sería algo así:

header('Content-type: application/json; charset=utf-8 '); // necesario
echo json_encode(array('ultimo_registro' => $numero_pedidos));

$numero_pedidos contendrá la cantidad de pedidos desde la base de datos.

reemplaza esto:

if( data.ultimo_registro != ultimo_registro ) {

por esto:

if( ultimo_registro !== null && data.ultimo_registro != ultimo_registro ) {

0voto

danielreales7 comentado

Sí ya lo devuelve, pero a la función no la llamo desde ningún sitio?

0voto

white comentado

la funcion check_new_records()? puedes llamarla cuando el dom este listo

    <script type="text/javascript">
        // function check_new_records() { ...

        $(document).ready(check_new_records);
    </script>
</body>

PD: me parece que la pagina nunca se va a actualizar por que ultimo_registro siempre es nulo, esta linea:

ultimo_registro = data.ultimo_registro

ponla despues de:

setTimeout(check_new_records, 100);

0voto

danielreales7 comentado

No me está entrando dentro, ahora sí lo está realizando bien pero cuando llamo a data.ultimo_registro me devuelve undefined.
El archivo PHP si lo ejecuto desde el navegador me devuelve lo siguiente [{"ultimo_registro":"3"}]

0voto

white comentado

es undefined por que el objeto que devuelves es un arreglo, el json esperado debería tener esta forma: {"ultimo_registro":"3"}

si lo devuelves de esta forma: [{"ultimo_registro":"3"}] entonces cambia esto:

data.ultimo_registro

por esto:

data[0].ultimo_registro

0voto

danielreales7 comentado

Ahora si lo coge bien, pero sigue sin entrar dentro de la sentencia if. Me estoy fijando que no actualiza la variable var ultimo_registro = null. Siempre es null.

0voto

white comentado

te aseguraste que la linea ultimo_registro = data.ultimo_registro; este fuera del if y despues de:

setTimeout(check_new_records, 100);

?

PD: estas seguro que deseas enviar cada 100 milisegundos la petición? podría estar saturando tu servidor.

0voto

danielreales7 comentado

function check_new_records()
    {
        $.ajax({
            method: 'GET',
            url: 'http://www.xxx.com/xx/xx/refresh_page.php',
            dataType: 'json',
            success: function(data)
            {
                if( ultimo_registro !== null && data[0].ultimo_registro != ultimo_registro ) {
                    // actualizar panel
                    playSound();
                    location.reload();
                    ultimo_registro = data[0].ultimo_registro;
                }
                setTimeout(check_new_records, 1000);
            }
        });
    }

Ahí es donde la tenía, donde me dijistes antes.
La dejo ahí y donde me has dicho ahora no? O solo donde me has dicho ahora.

Ya lo de los segundos lo voy a cambiar, es solo prueba.

0voto

danielreales7 comentado

Listo, vaya tontería te acabo de preguntar. Muchísimas gracias por todo!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta