Puede resolver este problema usando ZeroMQ.
ZeroMQ es una biblioteca que proporciona conectores supercargados para conectar cosas (hilos, procesos e incluso máquinas separadas) juntas.
Supongo que está intentando enviar datos desde el servidor al cliente. Bueno, una buena forma de hacerlo es usando el EventSource API (polyfills available).
Client.js
conecta a través de stream.php EventSource.
var stream = new EventSource('stream.php');
stream.addEventListener('debug', function (event) {
var data = JSON.parse(event.data);
console.log([event.type, data]);
});
stream.addEventListener('message', function (event) {
var data = JSON.parse(event.data);
console.log([event.type, data]);
});
router.php
Este es un proceso de larga duración que escucha los mensajes entrantes y los envía a cualquiera que escuche.
<?php
$context = new ZMQContext();
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind("tcp://*:5555");
$pub = $context->getSocket(ZMQ::SOCKET_PUB);
$pub->bind("tcp://*:5556");
while (true) {
$msg = $pull->recv();
echo "publishing received message $msg\n";
$pub->send($msg);
}
stream.php
Cada usuario que se conecta al sitio obtiene su propia stream.php. Este script es de larga ejecución y espera mensajes del enrutador. Una vez que recibe un nuevo mensaje, este mensaje se enviará en formato EventSource.
<?php
$context = new ZMQContext();
$sock = $context->getSocket(ZMQ::SOCKET_SUB);
$sock->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, "");
$sock->connect("tcp://127.0.0.1:5556");
set_time_limit(0);
ini_set('memory_limit', '512M');
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
while (true) {
$msg = $sock->recv();
$event = json_decode($msg, true);
if (isset($event['type'])) {
echo "event: {$event['type']}\n";
}
$data = json_encode($event['data']);
echo "data: $data\n\n";
ob_flush();
flush();
}
Para enviar mensajes a todos los usuarios, simplemente envíelos al enrutador. El enrutador luego distribuirá ese mensaje a todas las transmisiones de escucha. Aquí hay un ejemplo:
<?php
$context = new ZMQContext();
$sock = $context->getSocket(ZMQ::SOCKET_PUSH);
$sock->connect("tcp://127.0.0.1:5555");
$msg = json_encode(array('type' => 'debug', 'data' => array('foo', 'bar', 'baz')));
$sock->send($msg);
$msg = json_encode(array('data' => array('foo', 'bar', 'baz')));
$sock->send($msg);
Esto debería demostrar que no necesita node.js para hacer programación en tiempo real. PHP puede manejarlo bien.
Aparte de eso, socket.io es una muy buena manera de hacerlo. Y puede conectarse a socket.io a su código PHP a través de ZeroMQ fácilmente.
Ver también
¿Qué estás tratando de lograr? El método habitual es hacer que el cliente llame al script periódicamente para verificar los cambios. ¿Hay alguna razón por la que quieres hacerlo desde el servidor? – JJJ
PHP no es realmente un lenguaje que debe usar para COMET. Use el nodojs o algo más que funciona de forma asíncrona (python tornado o greenlets, por ejemplo). Al utilizar PHP ejecutándose en un servidor web basado en hilos/proceso, tiene una gran sobrecarga. – ThiefMaster
@Juhana, la razón es 'evitar 'la comprobación periódica de cambio y tener una solución' reverse-ajax'. @thiefMaster Sé que hay alguna solución de servidor COMET, pero realmente creo que un back-end php puede ser posible, y mientras escriba mi inicio de sesión empresarial en PHP, sería mejor no volver a escribir en otro idioma evitando el código duplicación. ¿Puedes explicarme por qué un backend de cometa PHP sería ese overheading? – ArtoAle