tenia rizado recogidos porque pelo peinados origen ondulando ondulado liso lacio hay genetica esta encrespo con cambio cabello bucles alisando php server-sent-events

php - rizado - Mientras que los bucles para eventos enviados por el servidor están causando que la página se congele



porque mi cabello se esta ondulando (9)

Actualmente estoy trabajando en un chat que utiliza eventos enviados por el servidor para recibir los mensajes. Sin embargo, estoy teniendo un problema. El evento enviado por el servidor nunca se conecta y permanece pendiente porque la página no se carga.

Por ejemplo:

<?php while(true) { echo "data: This is the message."; sleep(3); ob_flush(); flush(); } ?>

Espero que cada 3 segundos, "datos: este es el mensaje". será emitido. En su lugar, la página simplemente no se carga. Sin embargo, necesito este comportamiento para eventos enviados por el servidor. ¿Hay una manera de solucionar esto?

Editar:

Código Completo:

<?php session_start(); require "connect.php"; require "user.php"; session_write_close(); echo $data["number"]; header("Content-Type: text/event-stream/n/n"); header(''Cache-Control: no-cache''); set_time_limit(1200); $store = new StdClass(); // STORE LATEST MESSAGES TO COMPARE TO NEW ONES $ms = 200; // REFRESH TIMING (in ms) $go = true; // MESSAGE CHANGED function formateNumber ($n) { $areaCode = substr($n, 0, 3); $part1 = substr($n, 3, 3); $part2 = substr($n, 6, 4); return "($areaCode) $part1-$part2"; } function shorten ($str, $mLen, $elp) { if (strlen($str) <= $mLen) { return $str; } else { return rtrim(substr($str, 0, $mLen)) . $elp; } } do { $number = $data["number"]; $sidebarQ = " SELECT * FROM ( SELECT * FROM messages WHERE deleted NOT LIKE ''%$number%'' AND ( `from`=''$number'' OR `to`=''$number'' ) ORDER BY `timestamp` DESC ) as mess GROUP BY `id` ORDER BY `timestamp` DESC"; $query = $mysqli->query($sidebarQ); if ($query->num_rows == 0) { echo ''data: null'' . $number; echo "/n/n"; } else { $qr = array(); while($row = $query->fetch_assoc()) { $qr[] = $row; } foreach ($qr as $c) { $id = $c["id"]; if (!isset($store->{$id})) { $store->{$id} = $c["messageId"]; $go = true; } else { if ($store->{$id} != $c["messageId"]) { $go = true; $store->{$id} = $c["messageId"]; } } } if($go == true) { $el = $n = ""; foreach ($qr as $rows) { $to = $rows["to"]; $id = $rows["id"]; $choose = $to == $number ? $rows["from"] : $to; $nameQuery = $mysqli->query("SELECT `savedname` FROM `contacts` WHERE `friend`=''$choose'' AND `number`=''$number''"); $nameGet = $nameQuery->fetch_assoc(); $hasName = $nameQuery->num_rows == 0 ? formateNumber($choose) : $nameGet["savedname"]; $new = $mysqli->query("SELECT `id` FROM `messages` WHERE `to`=''$number'' AND `tostatus`=''0'' AND `id`=''$id''")->num_rows; if ($new > 0) { $n = "<span class=''new''>" . $new . "</span>"; } $side = "<span style=''color:#222''>" . ($to == $number ? "To you:" : "From you:") . "</span>"; $el .= "<div class=''messageBox sBox" . ($nameQuery->num_rows == 0 ? " noname" : "") . "'' onclick=/"GLOBAL.load($id, $choose)/" data-id=''$id''><name>$hasName</name><div>$side " . shorten($rows["message"], 25, "...") . "</div>$n</div>"; } echo ''data: ''. $el; echo "/n/n"; $go = false; } } echo " "; ob_flush(); flush(); sleep(2); } while(true); ?>

También me gustaría señalar que este bucle infinito no debería estar causando que esto suceda. Esta es la forma en que se configuran los SSE normalmente, e incluso se hace en el sitio web de MDN.


¿Podría ser tan simple como el tiempo de espera del script?

Finalmente, los scripts de PHP terminan automáticamente si se ejecutan durante demasiado tiempo. La solución para cuando no quiera que esto suceda es seguir reiniciando el tiempo de espera.

Así que una simple adición podría ser todo lo que necesitas:

<?php while(true) { echo "data: This is the message."; set_time_limit(30); sleep(3); ob_flush(); flush(); } ?>

Por supuesto, puede que no sea así, pero mi instinto es que este es el problema.

ACTUALIZACIÓN: Me di cuenta en los comentarios que está utilizando algún alojamiento gratuito. Si están ejecutando PHP en safe mode no podrá restablecer su tiempo de espera.


El siguiente código funciona bien aquí, también usa Mayhem su función str_repeat para agregar 4k de datos (que suele ser el mínimo para que un paquete tcp sea eliminado por php)

echo str_repeat('' '', 4096); while(true) { echo "data: This is the message."; flush(); sleep(3); }


En lugar de usar el bucle, pruebe este código que se proporciona a continuación, que funciona (probado) bien según sus requisitos

echo "data: This is the message."; $url1="<your-page-name>.php"; header("Refresh: 5; URL=$url1");

Lo que esto hará es que se llamará a sí mismo cada 5 segundos (en su caso, configurarlo en 3 en lugar de 5) y se hará eco de la salida.

Espero que esto solucione tu problema


No hay duda de que ahora ya lo has resuelto, pero en el caso de que no hayas utilizado código como el siguiente en un par de scripts sse y funcionó a la perfección. El código a continuación es genérico y no presenta el procesamiento de su sql o conjunto de registros, pero la idea es sólida (!?)

<?php set_time_limit( 0 ); ini_set(''auto_detect_line_endings'', 1); ini_set(''mysql.connect_timeout'',''7200''); ini_set(''max_execution_time'', ''0''); date_default_timezone_set( ''Europe/London'' ); ob_end_clean(); gc_enable(); header(''Content-Type: text/event-stream''); header(''Cache-Control: no-cache''); header(''Access-Control-Allow-Credentials: true''); header(''Access-Control-Allow-Methods: GET''); header(''Access-Control-Expose-Headers: X-Events''); if( !function_exists(''sse_message'') ){ function sse_message( $evtname=''chat'', $data=null, $retry=1000 ){ if( !is_null( $data ) ){ echo "event:".$evtname."/r/n"; echo "retry:".$retry."/r/n"; echo "data:" . json_encode( $data, JSON_FORCE_OBJECT|JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS ); echo "/r/n/r/n"; } } } $sleep=1; $c=1; $pdo=new dbpdo();/* wrapper class for PDO that simplifies using PDO */ while( true ){ if( connection_status() != CONNECTION_NORMAL or connection_aborted() ) { break; } /* Infinite loop is running - perform actions you need */ /* Query database */ /* $sql=''select * from `table`''; $res=$pdo->query($sql); */ /* Process recordset from db */ /* $payload=array(); foreach( $res as $rs ){ $payload[]=array(''message''=>$rs->message); } */ /* prepare sse message */ sse_message( ''chat'', array(''field''=>''blah blah blah'',''id''=>''XYZ'',''payload''=>$payload ) ); /* Send output */ if( @ob_get_level() > 0 ) for( $i=0; $i < @ob_get_level(); $i++ ) @ob_flush(); @flush(); /* wait */ sleep( $sleep ); $c++; if( $c % 1000 == 0 ){/* I used this whilst streaming twitter data to try to reduce memory leaks */ gc_collect_cycles(); $c=1; } } if( @ob_get_level() > 0 ) { for( $i=0; $i < @ob_get_level(); $i++ ) @ob_flush(); @ob_end_clean(); } ?>


Parece que la función de dormir está interfiriendo con la salida. Poner la función de suspensión DESPUÉS funcionó:

<?php while(true) { echo "data: This is the message."; ob_flush(); flush(); sleep(3); }

Como sugieren otras personas, recomendaría usar AJAX en lugar de un bucle infinito, pero esa no fue tu pregunta.


Si bien esta no es una respuesta directa al problema, intente usar este método para encontrar el error ... ¿No está obteniendo errores, pero esto debería ayudarlo a encontrarlos?

Básicamente, desea tener un script PHP simple que incluya su script principal, pero esta página permite errores ... Ejemplo a continuación ...

index.php / Simple Error Includer

<?php ini_set(''display_errors'',1); ini_set(''display_startup_errors'',1); error_reporting(-1); require "other.php"; ?>

other.php / You Script principal

<?php ini_set(''display_errors'',1); ini_set(''display_startup_errors'',1); error_reporting(-1); weqwe qweqeq qweqweqweqwe ?>

Si crea una configuración como esta, si ve index.php verá el siguiente error Parse error: syntax error, unexpected ''qweqeq'' (T_STRING) in /var/www/html/syntax_errors/other.php on line 5 porque no tiene una sintaxis no válida en la página principal y permite que cualquier incluido sea revisado por error.

Pero si usted ve dónde otro.php, simplemente obtendrá una página en blanco / en blanco porque no puede validar toda la página / script.

Utilizo este método en mis proyectos, de esa manera, independientemente de lo que haga en other.php o en cualquier página php vinculada, veré un informe de errores para ellos.

Entienda el código antes de comentar para decir que esto deshabilita el control de errores significa que no se molestó en RTM

Llenar el buffer

Otro problema en el pasado que recuerdo fue llenar el búfer antes de que saliera al navegador. Así que intente algo como esto antes de su bucle.

echo str_repeat("/n",4096); // Exceed the required browser threshold for($i=0;$i<70;$i++) { echo "something as normal"; flush(); sleep(1); }

Ejemplos en http://www.sitepoint.com/php-streaming-output-buffering-explained/


Sugiero usar la instrucción if () en lugar de usar while. Y en tu caso tu condición es siempre cierta, por lo tanto, está en un bucle infinito.


Una cosa que he notado aquí es sleep() función sleep() en combinación con ob_start() y - NO HAY - ob_start () en cualquier lugar del código completo, sin embargo, hay flush() y ob_flush() ..

¿Qué estás ruborizando de todos modos? ¿Y por qué no simplemente ob_end_flush() ?

Lo que pasa es que sleep() que echo() , que sleep() otra vez, que echo() otra vez, etc, etc. no tiene ningún efecto cuando el búfer de salida está activado. La función de suspensión funciona como se esperaba cuando el búfer de salida no está en juego. De hecho, podría * (y lo hará) producir resultados bastante inesperados, y esos resultados no serán los que queremos ver.


Voy a tomar una oportunidad y decir lo obvio,

puede consultar el servidor cada 3 segundos y dejar que el cliente haga la espera ...

Esto podría hacerse fácilmente con javascript

por ejemplo, intente este código y nombre si file.php

<?php $action=''''; if (array_key_exists(''action'',$_GET)) {$action=$_GET[''action''];} if ($action==''poll'') { echo "this message will be sent every 3 sec"; } else { ?><HTML><HEAD> <SCRIPT SRC="http://code.jquery.com/jquery-2.1.3.min.js"></SCRIPT> <SCRIPT> function doPoll() { $(''#response'').append($.get("file.php?action=poll")); setTimeout(doPoll, 3000); } doPoll(); </SCRIPT> </HEAD><BODY><DIV id="response"></DIV></BODY></HTML><?php }