eventsource - PHP and events - flush to client does not happen until the script dies -
i trying create simple page sends events web page cannot php send output before page terminates.
i using php-fpm , php5.6.27.
this simple html page:
<html> <head> <title>test events</title> </head> <body> testing events <ul id="pingeventlist" style="float: left"></ul> <ul id="messageeventlist" style="float: left"></ul> <script> var evtsource=new eventsource("./s_events.php?auth=e3b164ef33d802c45da829b8f1240d16"); var pingeventlist=document.getelementbyid('pingeventlist'); var messageeventlist=document.getelementbyid('messageeventlist'); evtsource.onmessage=function (e){ var newelement=document.createelement("li"); newelement.innerhtml="message: "+e.data; messageeventlist.appendchild(newelement); }; evtsource.addeventlistener("initial", function (e){ var newelement=document.createelement("li"); // var obj=json.parse(e.data); newelement.innerhtml="initial info "+e.data; console.log("initial info "+e.data); pingeventlist.appendchild(newelement); }, false); evtsource.addeventlistener("modified", function (e){ var newelement=document.createelement("li"); // var obj=json.parse(e.data); newelement.innerhtml="modified info "+e.data; console.log("modified info "+e.data); pingeventlist.appendchild(newelement); }, false); evtsource.onerror=function (e){ console.log("eventsource failed.", e); // while(pingeventlist.firstchild){ // pingeventlist.removechild(pingeventlist.firstchild); // } // alert("eventsource failed."); }; // evtsource.close(); </script> </body> </html>
and php page:
<?php @set_time_limit(0); // disable time limit // prevent buffering if(function_exists('apache_setenv')){ @apache_setenv('no-gzip', 1); } @ini_set('zlib.output_compression', 0); @ini_set('implicit_flush', 1); while(ob_get_level() !=0){ ob_end_flush(); } ob_implicit_flush(1); ignore_user_abort(false); header('access-control-allow-origin: *'); header('access-control-allow-credentials: true'); header('content-type: text/event-stream'); header('cache-control: no-cache'); // recommended prevent caching of event data. header('x-accel-buffering: off'); // disables fastcgi buffering on nginx $sleep_time = 1; //0.5 // seconds sleep after data has been sent $exec_limit_time = 15; //600; // time limit of script in seconds $keep_alive_time = 30; //300; // interval of sending signal keep connection alive $client_reconnect = 1; // time client reconnect after connection has lost in seconds $keep_alive_start = time(); $exec_limit_start = time(); $ts_last_used = intval(isset($_server["http_last_event_id"])?$_server["http_last_event_id"]:0); echo 'retry:'.($client_reconnect*1000)."\n"; $event = [ 'id' => $ts_last_used++, 'event' => 'initial', 'data' => "[\ndata:".'initial data'."\ndata:]", ]; _send_event_data($event); while(1){ // did connection fail? if(connection_status() !=connection_normal){ break; }else{ $event = [ 'id' => $ts_last_used++, 'event' => 'modified', 'data' => '{"id":"stuff here too"}', ]; _send_event_data($event); } // sleep x seconds usleep($sleep_time*1000000); if($exec_limit_start+$exec_limit_time<time()){ break; } if($keep_alive_start+$keep_alive_time<time()){ $keep_alive_start = time(); echo ': '.sha1(mt_rand())."\n\n"; } } // if reached, 'break' // triggered inside while loop // // here can log, or perform other tasks // need without being dependent on // browser. function _send_event_data($info){ global $keep_alive_start; if(isset($info['id'])){ echo 'id:'.$info['id']."\n"; } if(isset($info['event'])){ echo 'event:'.$info['event']."\n"; } echo 'data:'.$info['data']."\n"; if(!isset($info['more_to_come'])||!$info['more_to_come']){ echo "\n"; } $keep_alive_start = time(); @ob_end_flush(); flush(); }
i have tried various possible solutions, cannot figure out. have changed php-fpm mod_php (i using apache) in case php_fpm, didn't have success.
i open suggestions
i figured out... apache holding output, new configuration fast-cgi usign php-fpm:
<ifmodule fastcgi_module> #php-fpm addhandler php5-fcgi .php .html action php5-fcgi /php5-fcgi alias /php5-fcgi /usr/local/www/cgi-bin/php5-fcgi fastcgiexternalserver /usr/local/www/cgi-bin/php5-fcgi -flush -socket /var/run/php-fpm.sock -pass-header authorization -idle-timeout 600 <directory /usr/local/www/cgi-bin> require granted </directory> </ifmodule>
what made difference -flush
added fastcgiexternalserver
, output not buffered anymore , output right away (i able find answer page: http://www.jeffgeerling.com/blog/2016/streaming-php-disabling-output-buffering-php-apache-nginx-and-varnish )
Comments
Post a Comment