<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/class.eventhttpconnection.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'es',
  ),
  'this' => 
  array (
    0 => 'eventhttpconnection.setclosecallback.php',
    1 => 'EventHttpConnection::setCloseCallback',
    2 => 'Define una funci&oacute;n de retrollamada al cerrar la conexi&oacute;n',
  ),
  'up' => 
  array (
    0 => 'class.eventhttpconnection.php',
    1 => 'EventHttpConnection',
  ),
  'prev' => 
  array (
    0 => 'eventhttpconnection.makerequest.php',
    1 => 'EventHttpConnection::makeRequest',
  ),
  'next' => 
  array (
    0 => 'eventhttpconnection.setlocaladdress.php',
    1 => 'EventHttpConnection::setLocalAddress',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    'path' => 'reference/event/eventhttpconnection/setclosecallback.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="eventhttpconnection.setclosecallback" class="refentry">
 <div class="refnamediv">
  <h1 class="refname">EventHttpConnection::setCloseCallback</h1>
  <p class="verinfo">(PECL event &gt;= 1.8.0)</p><p class="refpurpose"><span class="refname">EventHttpConnection::setCloseCallback</span> &mdash; <span class="dc-title">Define una función de retrollamada al cerrar la conexión</span></p>

 </div>
 <div class="refsect1 description" id="refsect1-eventhttpconnection.setclosecallback-description">
  <h3 class="title">Descripción</h3>
  <div class="methodsynopsis dc-description">
   <span class="modifier">public</span>
   <span class="modifier">function</span> <span class="methodname"><strong>EventHttpConnection::setCloseCallback</strong></span>(<span class="methodparam">
    
    <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span> <code class="parameter">$callback</code>
   </span>, <span class="methodparam">
    
    <span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span> <code class="parameter">$data</code>
   <span class="initializer"> = ?</span></span>): <span class="type"><a href="language.types.void.php" class="type void">void</a></span></div>

  <p class="para rdfs-comment">
   Define una función de retrollamada al cerrar la conexión.
  </p>
 </div>

 <div class="refsect1 parameters" id="refsect1-eventhttpconnection.setclosecallback-parameters">
  <h3 class="title">Parámetros</h3>
  <dl>
   
    <dt>
     <code class="parameter">callback</code>
    </dt>
    <dd>
     <p class="para">
      Función de retrollamada a llamar al cerrar la conexión.
      Debe corresponder al siguiente prototipo:
     </p>
     <div class="methodsynopsis dc-description">
      <span class="modifier">function</span> <span class="methodname"><strong>callback</strong></span>(<span class="methodparam">
       
       <span class="type"><a href="class.eventhttpconnection.php" class="type EventHttpConnection">EventHttpConnection</a></span> <code class="parameter">$conn</code>
       <span class="initializer"> = <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong></span>
      </span>, <span class="methodparam">
       
       <span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span> <code class="parameter">$arg</code>
       <span class="initializer"> = <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong></span>
      </span>): <span class="type"><a href="language.types.void.php" class="type void">void</a></span></div>

    </dd>
   
  </dl>
 </div>

 <div class="refsect1 returnvalues" id="refsect1-eventhttpconnection.setclosecallback-returnvalues">
  <h3 class="title">Valores devueltos</h3>
  <p class="para">
   No se retorna ningún valor.
  </p>
 </div>

 <div class="refsect1 examples" id="refsect1-eventhttpconnection.setclosecallback-examples">
  <h3 class="title">Ejemplos</h3>
  <div class="example" id="example-1">
   <p><strong>Ejemplo #1 Ejemplo con <span class="methodname"><strong>EventHttpConnection::setCloseCallback()</strong></span></strong></p>
   <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
</span><span style="color: #FF8000">/*
 * Configuración de la retrollamada de cierre de conexión
 *
 * El script maneja las conexiones cerradas utilizando la API HTTP.
 *
 * Uso:
 * 1) Iniciar el servidor:
 * $ php examples/http_closecb.php 4242
 *
 * 2) Iniciar un cliente en otra terminal. La sesión de tipo telnet
 * debe verse como sigue:
 *
 * $ nc -t 127.0.0.1 4242
 * GET / HTTP/1.0
 * Connection: close
 *
 * El servidor debe mostrar algo similar a lo siguiente:
 *
 * HTTP/1.0 200 OK
 * Content-Type: multipart/x-mixed-replace;boundary=boundarydonotcross
 * Connection: close
 *
 * &lt;html&gt;
 *
 * 3) Terminar la conexión del cliente abruptamente,
 * es decir, matar el proceso o simplemente presionar Ctrl-C.
 *
 * 4) Verificar si el servidor llamó a _close_callback.
 * El script debe mostrar la cadena "_close_callback" en la salida estándar.
 *
 * 5) Verificar si el proceso del servidor no tiene conexiones huérfanas,
 * por ejemplo, con la utilidad `lsof`.
 */

</span><span style="color: #007700">function </span><span style="color: #0000BB">_close_callback</span><span style="color: #007700">(</span><span style="color: #0000BB">$conn</span><span style="color: #007700">)
{
    echo </span><span style="color: #0000BB">__FUNCTION__</span><span style="color: #007700">, </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;
}

function </span><span style="color: #0000BB">_http_default</span><span style="color: #007700">(</span><span style="color: #0000BB">$req</span><span style="color: #007700">, </span><span style="color: #0000BB">$dummy</span><span style="color: #007700">)
{
    </span><span style="color: #0000BB">$conn </span><span style="color: #007700">= </span><span style="color: #0000BB">$req</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getConnection</span><span style="color: #007700">();
    </span><span style="color: #0000BB">$conn</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setCloseCallback</span><span style="color: #007700">(</span><span style="color: #DD0000">'_close_callback'</span><span style="color: #007700">, </span><span style="color: #0000BB">NULL</span><span style="color: #007700">);

    </span><span style="color: #FF8000">/*
    Al habilitar Event::READ se protege al servidor contra conexiones no cerradas.
    Esta es una peculiaridad de Libevent. La biblioteca deshabilita los eventos Event::READ
    en esta conexión, y el servidor no es notificado sobre las conexiones terminadas.

    Por lo tanto, cada vez que el cliente termina la conexión abruptamente, obtenemos una conexión huérfana. Por ejemplo, lo siguiente es parte del comando `lsof -p $PID | grep TCP`
    después de que el cliente ha terminado la conexión:

    57-php     15057 ruslan  6u  unix 0xffff8802fb59c780   0t0  125187 socket
    58:php     15057 ruslan  7u  IPv4             125189   0t0     TCP *:4242 (LISTEN)
    59:php     15057 ruslan  8u  IPv4             124342   0t0     TCP localhost:4242-&gt;localhost:37375 (CLOSE_WAIT)

    donde $PID es el ID del proceso.

    El siguiente bloque de código corrige este tipo de conexiones huérfanas.
     */
    </span><span style="color: #0000BB">$bev </span><span style="color: #007700">= </span><span style="color: #0000BB">$req</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getBufferEvent</span><span style="color: #007700">();
    </span><span style="color: #0000BB">$bev</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">enable</span><span style="color: #007700">(</span><span style="color: #0000BB">Event</span><span style="color: #007700">::</span><span style="color: #0000BB">READ</span><span style="color: #007700">);

    </span><span style="color: #FF8000">// Debemos liberarlo explícitamente. Ver EventHttpRequest::getConnection

    </span><span style="color: #0000BB">$bev</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">free</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Debemos liberarlo explícitamente

    </span><span style="color: #0000BB">$req</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">addHeader</span><span style="color: #007700">(
        </span><span style="color: #DD0000">'Content-Type'</span><span style="color: #007700">,
        </span><span style="color: #DD0000">'multipart/x-mixed-replace;boundary=boundarydonotcross'</span><span style="color: #007700">,
        </span><span style="color: #0000BB">EventHttpRequest</span><span style="color: #007700">::</span><span style="color: #0000BB">OUTPUT_HEADER
    </span><span style="color: #007700">);

    </span><span style="color: #0000BB">$buf </span><span style="color: #007700">= new </span><span style="color: #0000BB">EventBuffer</span><span style="color: #007700">();
    </span><span style="color: #0000BB">$buf</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #DD0000">'&lt;html&gt;'</span><span style="color: #007700">);

    </span><span style="color: #0000BB">$req</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sendReply</span><span style="color: #007700">(</span><span style="color: #0000BB">200</span><span style="color: #007700">, </span><span style="color: #DD0000">"OK"</span><span style="color: #007700">);
    </span><span style="color: #0000BB">$req</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sendReplyChunk</span><span style="color: #007700">(</span><span style="color: #0000BB">$buf</span><span style="color: #007700">);
}

</span><span style="color: #0000BB">$port </span><span style="color: #007700">= </span><span style="color: #0000BB">4242</span><span style="color: #007700">;
if (</span><span style="color: #0000BB">$argc </span><span style="color: #007700">&gt; </span><span style="color: #0000BB">1</span><span style="color: #007700">) {
    </span><span style="color: #0000BB">$port </span><span style="color: #007700">= (int) </span><span style="color: #0000BB">$argv</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">];
}
if (</span><span style="color: #0000BB">$port </span><span style="color: #007700">&lt;= </span><span style="color: #0000BB">0 </span><span style="color: #007700">|| </span><span style="color: #0000BB">$port </span><span style="color: #007700">&gt; </span><span style="color: #0000BB">65535</span><span style="color: #007700">) {
    exit(</span><span style="color: #DD0000">"Puerto no válido"</span><span style="color: #007700">);
}

</span><span style="color: #0000BB">$base </span><span style="color: #007700">= new </span><span style="color: #0000BB">EventBase</span><span style="color: #007700">();
</span><span style="color: #0000BB">$http </span><span style="color: #007700">= new </span><span style="color: #0000BB">EventHttp</span><span style="color: #007700">(</span><span style="color: #0000BB">$base</span><span style="color: #007700">);

</span><span style="color: #0000BB">$http</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setDefaultCallback</span><span style="color: #007700">(</span><span style="color: #DD0000">"_http_default"</span><span style="color: #007700">, </span><span style="color: #0000BB">NULL</span><span style="color: #007700">);
</span><span style="color: #0000BB">$http</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bind</span><span style="color: #007700">(</span><span style="color: #DD0000">"0.0.0.0"</span><span style="color: #007700">, </span><span style="color: #0000BB">$port</span><span style="color: #007700">);
</span><span style="color: #0000BB">$base</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">loop</span><span style="color: #007700">();

</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
   </div>

  </div>
 </div>

</div><?php manual_footer($setup); ?>