TigerZF
🌐Español

70.2. Trabajando con Zend_TimeSync

Zend_TimeSync puede devolver la hora actual de cualquier servidor de hora NTP o SNTP dado. Puede manejar automáticamente múltiples servidores y ofrece una interfaz simple.

[Note] Nota

Todos los ejemplos de este capítulo usan un servidor de hora público y genérico: 0.europe.pool.ntp.org. Debería usar un servidor de hora público y genérico que esté cerca de su servidor de aplicaciones. Consulte http://www.pool.ntp.org para más información.

70.2.1. Petición genérica a un servidor de hora

Solicitar la hora a un servidor de hora es sencillo. Primero, indica el servidor de hora del que desea solicitar la hora.

$server = new Zend_TimeSync('0.pool.ntp.org');

print $server->getDate()->getIso();

Entonces, ¿qué ocurre en segundo plano dentro de Zend_TimeSync? Primero se comprueba la sintaxis del servidor de hora. En nuestro ejemplo, '0.pool.ntp.org' se comprueba y se reconoce como una posible dirección para un servidor de hora. Después, al llamar a getDate(), se solicita al servidor de hora configurado y este devuelve su propia hora. Zend_TimeSync calcula entonces la diferencia con la hora real del servidor que ejecuta el script y devuelve un objeto Zend_Date con la hora correcta.

Para más detalles sobre Zend_Date y sus métodos, consulte la documentación de Zend_Date.

70.2.2. Múltiples servidores de hora

No todos los servidores de hora están siempre disponibles para devolver su hora. Los servidores pueden no estar disponibles durante tareas de mantenimiento, por ejemplo. Cuando no se puede solicitar la hora al servidor de hora, se produce una excepción.

Zend_TimeSync es una solución simple que puede manejar múltiples servidores de hora y admite un mecanismo de conmutación por error automático. Hay dos formas admitidas; puede especificar un array de servidores de hora al crear la instancia, o puede agregar servidores de hora adicionales a la instancia mediante el método addServer().

$server = new Zend_TimeSync(array('0.pool.ntp.org',
                                  '1.pool.ntp.org',
                                  '2.pool.ntp.org'));
$server->addServer('3.pool.ntp.org');

print $server->getDate()->getIso();

No hay límite en el número de servidores de hora que puede agregar. Cuando no se puede alcanzar un servidor de hora, Zend_TimeSync recurrirá al siguiente servidor de hora e intentará conectarse a él.

Cuando proporciona más de un servidor de hora, lo cual se considera una buena práctica para Zend_TimeSync, debería nombrar cada servidor. Puede nombrar sus servidores con claves de array, con el segundo parámetro en la instanciación, o con el segundo parámetro al agregar otro servidor de hora.

$server = new Zend_TimeSync(array('generic'  => '0.pool.ntp.org',
                                  'fallback' => '1.pool.ntp.org',
                                  'reserve'  => '2.pool.ntp.org'));
$server->addServer('3.pool.ntp.org', 'additional');

print $server->getDate()->getIso();

Nombrar los servidores de hora le permite solicitar un servidor de hora específico como veremos más adelante en este capítulo.

70.2.3. Protocolos de los servidores de hora

Existen diferentes tipos de servidores de hora. La mayoría de los servidores de hora públicos usan el protocolo NTP. Pero hay otros protocolos de sincronización de hora disponibles.

Se define el protocolo adecuado en la dirección del servidor de hora. Hay dos protocolos que admite Zend_TimeSync: NTP y SNTP. El protocolo predeterminado es NTP. Si usa NTP, puede omitir el protocolo en la dirección como se mostró en los ejemplos anteriores.

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org',
                                  'reserve'  => 'ntp:\\2.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

print $server->getDate()->getIso();

Zend_TimeSync puede manejar servidores de hora mixtos. Por lo tanto no está restringido a un solo protocolo; puede agregar cualquier servidor independientemente de su protocolo.

70.2.4. Uso de puertos para los servidores de hora

Como con cualquier protocolo de la red mundial, los protocolos NTP y SNTP usan puertos estándar. NTP usa el puerto 123 y SNTP usa el puerto 37.

Pero a veces el puerto que utilizan los protocolos difiere del estándar. Puede definir el puerto que debe usarse para cada servidor dentro de la dirección. Solo agregue el número de puerto después de la dirección. Si no se define ningún puerto, entonces Zend_TimeSync usará el puerto estándar.

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org:200',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com:399', 'additional');

print $server->getDate()->getIso();

70.2.5. Opciones de los servidores de hora

Solo hay una opción dentro de Zend_TimeSync que se usará internamente: timeout. Sin embargo, puede definir cualquier opción propia que necesite y solicitarla.

La opción timeout define el número de segundos tras los cuales se detecta una conexión como interrumpida cuando no hubo respuesta. El valor predeterminado es 1, lo que significa que Zend_TimeSync recurrirá al siguiente servidor de hora si el servidor de hora solicitado no responde en un segundo.

Con el método setOptions(), puede establecer cualquier opción. Esta función acepta un array donde la clave es la opción a establecer y el valor es el valor de dicha opción. Cualquier opción previamente establecida será sobrescrita por el nuevo valor. Si desea saber qué opciones están establecidas, use el método getOptions(). Acepta una clave que devuelve la opción indicada si se especifica, o, si no se establece ninguna clave, devolverá todas las opciones establecidas.

Zend_TimeSync::setOptions(array('timeout' => 3, 'myoption' => 'timesync'));
$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

print $server->getDate()->getIso();
print_r(Zend_TimeSync::getOptions();
print "Timeout = " . Zend_TimeSync::getOptions('timeout');

Como puede ver, las opciones de Zend_TimeSync son estáticas. Cada instancia de Zend_TimeSync usará las mismas opciones.

70.2.6. Uso de diferentes servidores de hora

El comportamiento predeterminado de Zend_TimeSync al solicitar una hora es solicitarla al primer servidor indicado. Pero a veces es útil establecer un servidor de hora diferente del cual solicitar la hora. Esto puede hacerse con el método setServer(). Para definir el servidor de hora usado, indique el alias como parámetro dentro del método. Para obtener el servidor de hora realmente usado, llame al método getServer(). Acepta un alias como parámetro que define el servidor de hora a devolver. Si no se indica ningún parámetro, se devolverá el servidor de hora actual.

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));
$server->addServer('sntp:\\internal.myserver.com', 'additional');

$actual = $server->getServer();
$server = $server->setServer('additional');

70.2.7. Información de los servidores de hora

Los servidores de hora no solo ofrecen la hora en sí, sino también información adicional. Puede obtener esta información con el método getInfo().

$server = new Zend_TimeSync(array('generic'  => 'ntp:\\0.pool.ntp.org',
                                  'fallback' => 'ntp:\\1.pool.ntp.org'));

print_r ($server->getInfo());

La información devuelta varía según el protocolo utilizado y también puede variar según el servidor utilizado.

70.2.8. Gestión de excepciones

Las excepciones se recopilan para todos los servidores de hora y se devuelven como un array. Así puede recorrer todas las excepciones lanzadas como se muestra en el siguiente ejemplo:

$serverlist = array(
        // invalid servers
        'invalid_a'  => 'ntp://a.foo.bar.org',
        'invalid_b'  => 'sntp://b.foo.bar.org',
);

$server = new Zend_TimeSync($serverlist);

try {
    $result = $server->getDate();
    echo $result->getIso();
} catch (Zend_TimeSync_Exception $e) {

    $exceptions = $e->get();

    foreach ($exceptions as $key => $myException) {
        echo $myException->getMessage();
        echo '<br />';
    }
}