Signatur
Beschreibung
EventBufferEvent ist Teil der Event-Extension und kapselt Libevents bufferevent-API. Ein Buffer-Event verwaltet automatisch einen Eingabe- und einen Ausgabepuffer (EventBuffer) und ruft benutzerdefinierte Callbacks auf, wenn Daten gelesen oder geschrieben werden können oder ein Fehler auftritt.
Im Gegensatz zu einfachen Event-Objekten übernimmt EventBufferEvent das Puffern vollständig: Eingehende Daten werden in einen internen Lese-Puffer geschrieben und stehen dann asynchron zur Verfügung; ausgehende Daten werden in einen Schreib-Puffer gelegt und bei Gelegenheit gesendet. Das reduziert den Boilerplate-Code für typische TCP-Client- und -Server-Implementierungen erheblich.
Typische Einsatzgebiete sind nicht-blockierende TCP-Verbindungen (Client und Server), SSL/TLS-gesicherte Streams (über EventBufferEvent::sslFilter() oder EventBufferEvent::sslSocket()), sowie Pipe-basierte IPC. Der Entwickler definiert Callbacks für Lesen, Schreiben und Ereignisse (Verbindungsaufbau, -trennung, Fehler) und delegiert den Rest an die Event-Schleife.
Wichtig: EventBufferEvent-Objekte müssen immer innerhalb einer laufenden EventBase-Schleife verwendet werden und sollten nicht über Prozesgrenzen hinweg geteilt werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $base Pflicht | EventBase | Die EventBase-Instanz, an die dieses Buffer-Event gebunden wird. |
|
| $socket | mixed | null | Ein Stream-Resource-Handle, eine Socket-Resource oder ein Integer (Socket-Deskriptor). Kann null sein, wenn der Socket später über EventBufferEvent::connect() gesetzt wird. |
| $options | int | 0 | Bitmaske aus EventBufferEvent::OPT_*-Konstanten, z. B. EventBufferEvent::OPT_CLOSE_ON_FREE oder EventBufferEvent::OPT_THREADSAFE. |
| $readcb | callable|null | null | Callback, der aufgerufen wird, wenn Daten im Lese-Puffer verfügbar sind. Signatur: function(EventBufferEvent $bev, mixed $arg): void. |
| $writecb | callable|null | null | Callback, der aufgerufen wird, wenn der Schreib-Puffer unter den Wasserzeichenwert fällt (d. h. Daten wurden gesendet). Selbe Signatur wie readcb. |
| $eventcb | callable|null | null | Callback für Verbindungsereignisse (Verbindungsaufbau, -trennung, Fehler). Signatur: function(EventBufferEvent $bev, int $events, mixed $arg): void. $events ist eine Bitmaske aus EventBufferEvent::EOF, EventBufferEvent::ERROR, EventBufferEvent::CONNECTED usw. |
| $arg | mixed | null | Beliebiges Argument, das an alle Callbacks als letzten Parameter weitergegeben wird. |
Beispiele
Einfacher nicht-blockierender TCP-Echo-Client
<?php
$base = new EventBase();
$bev = new EventBufferEvent(
$base,
null,
EventBufferEvent::OPT_CLOSE_ON_FREE,
function (EventBufferEvent $bev, $arg) {
// Lese-Callback: alle verfügbaren Daten aus dem Puffer holen
$data = $bev->getInput()->read(1024);
echo "Empfangen: " . $data . PHP_EOL;
},
null,
function (EventBufferEvent $bev, int $events, $arg) use ($base) {
if ($events & EventBufferEvent::CONNECTED) {
echo "Verbunden!" . PHP_EOL;
// Nachricht senden
$bev->write("Hello, Server!\n");
} elseif ($events & (EventBufferEvent::ERROR | EventBufferEvent::EOF)) {
echo "Verbindungsfehler oder EOF" . PHP_EOL;
$base->exit();
}
}
);
$bev->enable(Event::READ | Event::WRITE);
$bev->connect("127.0.0.1", 12345);
$base->dispatch();
SSL/TLS-Verbindung mit EventBufferEvent::sslSocket()
<?php
$base = new EventBase();
$ctx = new EventSslContext(
EventSslContext::TLS_CLIENT_METHOD,
[
EventSslContext::OPT_VERIFY_PEER => false,
]
);
$bev = EventBufferEvent::sslSocket(
$base,
null,
$ctx,
EventBufferEvent::SSL_CONNECTING,
EventBufferEvent::OPT_CLOSE_ON_FREE
);
$bev->setCallbacks(
function (EventBufferEvent $bev) {
echo $bev->getInput()->read(4096);
},
null,
function (EventBufferEvent $bev, int $events) use ($base) {
if ($events & EventBufferEvent::CONNECTED) {
// HTTP-Anfrage über TLS senden
$bev->write("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");
} elseif ($events & EventBufferEvent::EOF) {
$base->exit();
}
}
);
$bev->enable(Event::READ | Event::WRITE);
$bev->connectHost($base->getDnsBase(), 'example.com', 443);
$base->dispatch();
// Wichtig · Fallstricke
Wasserzeichen (Watermarks): Mit EventBufferEvent::setWatermark() lässt sich steuern, ab welcher Datenmenge der Lese-Callback ausgelöst wird. Das verhindert unnötig häufige Callbacks bei kleinen Datenpaketen.
Thread-Sicherheit: Bei Verwendung in mehreren Threads muss die Option EventBufferEvent::OPT_THREADSAFE gesetzt und EventBase mit EventConfig::FEATURE_FDS konfiguriert werden.
Ressourcen-Verwaltung: Ein EventBufferEvent-Objekt gibt den zugehörigen Socket nur dann automatisch frei, wenn EventBufferEvent::OPT_CLOSE_ON_FREE gesetzt ist. Andernfalls muss der Socket manuell geschlossen werden.
Achtung bei SSL: Die SSL-Methoden (sslSocket, sslFilter) erfordern, dass PHP mit OpenSSL-Unterstützung kompiliert und die Event-Extension mit SSL-Unterstützung gebaut wurde.