Ir al contenido

Servidor de notificaciones

Histrix incluye un servidor de notificaciones en tiempo real construido sobre Thruway y Ratchet. Implementa WAMP: el servidor actúa como router de mensajes y los clientes publican o se suscriben a canales.

Ventana de terminal
php histrix push-server [0.0.0.0:8888]

Sin argumentos escucha en 0.0.0.0:8888. El router usa el realm realm1 y autentica a los clientes con WAMP-CRA contra los usuarios de la base.

\Histrix\Push\Event::publish($canal, (array) $contenido);
\Histrix\Push\Event::publish(
'nueva_oferta',
['xml' => 'oferta_crud.xml', 'user' => 'user_id']
);

El canal se prefija automáticamente con el id de la base, de modo que nueva_oferta se publica como {base}.nueva_oferta y las bases quedan aisladas entre sí. Al mensaje se le agregan el usuario que lo emitió y la marca de tiempo.

La publicación se hace por ZMQ hacia tcp://localhost:5555, así que el proceso web necesita la extensión ZMQ de PHP. Si no está cargada, publish no hace nada y no interrumpe la operación en curso.

Dentro de un <ejecuta> de un XML de tipo nosql:

<?xml version="1.0" encoding="UTF-8"?>
<histrix tipo="nosql" evento="insert">
<title>Oferta</title>
<obs/>
<form>
<table id="HAC_OFERTAS" label="Oferta">
<ejecuta>
<![CDATA[
\Histrix\Push\Event::publish(
'nueva_oferta',
['xml' => 'oferta_crud.xml', 'user' => 'user_id']
);
loger('notifico oferta');
]]>
</ejecuta>
<field id="id_oferta" id_temp="id_oferta">
</field>
</table>
</form>
</histrix>

El cliente usa Autobahn. La conexión la abre el propio motor al iniciar la sesión: se conecta a la ruta /wss/ del mismo host —que el servidor web enruta al puerto del push server—, con el realm realm1 y autenticación wampcra, y queda suscripto al canal personal del usuario ({base}.{user_id}).

var protocol = (window.location.protocol == 'https:') ? 'wss' : 'ws';
var connection = new autobahn.Connection({
url: protocol + '://' + Histrix.host + '/wss/',
realm: 'realm1',
authid: Histrix.user,
authmethods: ['wampcra'],
onchallenge: onchallenge
});
connection.onopen = function (session) {
session.subscribe(Histrix.db + '.' + Histrix.user_id, function (args) {
Histrix.showMsg(args[0] + ' - ' + args[1]);
});
Histrix.wsConnection = session;
};
connection.open();

Para suscribirse a un canal adicional desde código propio, con la conexión ya abierta:

if (Histrix.wsConnection && Histrix.wsConnection.isOpen) {
Histrix.wsConnection.subscribe(Histrix.db + '.mi_canal', function (args) {
Histrix.showMsg(args[0]);
});
}

Y para publicar desde el navegador:

Histrix.wsConnection.publish(Histrix.db + '.mi_canal', ['Hola']);