Signatur
Beschreibung
ZMQPoll ist Teil der PHP-Erweiterung ZMQ (ZeroMQ) und erlaubt es, mehrere Sockets gleichzeitig auf eingehende Nachrichten oder Schreibbereitschaft zu überwachen – ähnlich wie der Unix-Systemaufruf poll() oder select(). Statt in einer Endlosschleife jeden Socket einzeln abzufragen, wartet ZMQPoll effizient auf das erste aktive Ereignis.
Typischer Anwendungsfall ist ein Server oder Broker, der mehrere Kommunikationskanäle (z. B. Frontend- und Backend-Sockets) parallel bedient. Sobald einer der registrierten Sockets bereit ist, gibt poll() die Anzahl der bereiten Sockets zurück und füllt die übergebenen Arrays mit den jeweils lesbaren und/oder schreibbaren Sockets.
Sockets werden der Instanz mit add() hinzugefügt und können mit remove() wieder entfernt werden. Über die Konstanten ZMQ::POLL_IN und ZMQ::POLL_OUT (bitweise kombinierbar) legt man fest, auf welche Ereignistypen gewartet werden soll.
Fehler beim Polling werden nicht als Exceptions geworfen, sondern in einem internen Fehlerpuffer gespeichert, der über getLastErrors() ausgelesen werden kann.
Beispiele
Einfacher Poll-Loop mit zwei Sockets
<?php
$context = new ZMQContext();
// Frontend-Socket (empfängt von Clients)
$frontend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER);
$frontend->bind('tcp://*:5559');
// Backend-Socket (kommuniziert mit Workern)
$backend = new ZMQSocket($context, ZMQ::SOCKET_DEALER);
$backend->bind('tcp://*:5560');
$poll = new ZMQPoll();
$poll->add($frontend, ZMQ::POLL_IN);
$poll->add($backend, ZMQ::POLL_IN);
$readable = [];
$writeable = [];
while (true) {
$events = $poll->poll($readable, $writeable, 1000); // 1000 ms Timeout
if ($events === false) {
// Fehler auswerten
$errors = $poll->getLastErrors();
foreach ($errors as $error) {
echo 'Poll-Fehler: ' . $error . PHP_EOL;
}
continue;
}
foreach ($readable as $socket) {
$message = $socket->recvMulti();
if ($socket === $frontend) {
// Nachricht vom Client an Worker weiterleiten
$backend->sendMulti($message);
} else {
// Antwort vom Worker an Client zurückschicken
$frontend->sendMulti($message);
}
}
}
Socket aus dem Poll entfernen und Anzahl der registrierten Sockets prüfen
<?php
$context = new ZMQContext();
$socketA = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$socketA->bind('tcp://*:5561');
$socketB = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$socketB->bind('tcp://*:5562');
$poll = new ZMQPoll();
$idA = $poll->add($socketA, ZMQ::POLL_IN);
$idB = $poll->add($socketB, ZMQ::POLL_IN);
echo 'Registrierte Sockets: ' . $poll->count() . PHP_EOL; // 2
// Socket A wieder entfernen
$poll->remove($socketA);
echo 'Nach remove(): ' . $poll->count() . PHP_EOL; // 1
$readable = [];
$writeable = [];
$events = $poll->poll($readable, $writeable, 500);
echo 'Ereignisse innerhalb 500 ms: ' . (int)$events . PHP_EOL;
// Wichtig · Fallstricke
Timeout-Einheit: Der Timeout-Parameter von poll() wird in Millisekunden angegeben. Ein Wert von -1 bedeutet unbegrenztes Warten (blockierend), 0 kehrt sofort zurück.
Fehlerbehandlung: Im Gegensatz zu vielen anderen ZMQ-Methoden wirft poll() bei bestimmten Fehlern (z. B. unterbrochener Systemaufruf durch Signal) keine ZMQException, sondern gibt false zurück. Die konkreten Fehlermeldungen sind anschließend über getLastErrors() abrufbar.
Thread-Sicherheit: ZeroMQ-Sockets sind nicht thread-sicher. ZMQPoll darf nur innerhalb desselben Threads verwendet werden, in dem die registrierten Sockets erzeugt wurden.
Plattform: Die ZMQ-Erweiterung muss separat installiert werden (PECL-Paket zmq). Sie ist nicht im Standard-PHP-Lieferumfang enthalten.