Signatur
Beschreibung
Swoole\WebSocket\Frame ist ein Datenobjekt (Value Object), das einen empfangenen oder zu sendenden WebSocket-Frame abbildet. Beim Empfangen von Nachrichten über einen Swoole-WebSocket-Server werden Instanzen dieser Klasse automatisch erzeugt und an die onMessage-Callback-Funktion übergeben.
Ein Frame enthält neben den eigentlichen Nutzdaten ($data) auch Metainformationen wie den Opcode (Text, Binary, Ping, Pong, Close), die Verbindungs-ID ($fd), die Länge der Nutzdaten ($length) sowie Flags für das FIN-Bit und die Maskierung. Diese Informationen sind besonders wichtig, wenn man zwischen unterschiedlichen Frame-Typen (z. B. Text vs. Binary oder Ping/Pong-Keepalive-Frames) unterscheiden möchte.
Zum aktiven Senden kann ein Frame-Objekt manuell instanziiert, befüllt und an Swoole\WebSocket\Server::push() übergeben werden. Alternativ kann auch direkt ein String übergeben werden; die Frame-Klasse bietet jedoch mehr Kontrolle über Opcode und FIN-Bit, was bei der Implementierung von WebSocket-Erweiterungen oder Custom-Protokollen nützlich ist.
- $fd: Dateideskriptor der Verbindung (wird beim Empfang automatisch gesetzt).
- $data: Die eigentlichen Nutzdaten als String.
- $opcode: Opcode nach RFC 6455 (1 = Text, 2 = Binary, 8 = Close, 9 = Ping, 10 = Pong).
- $finish: Gibt an, ob dies der letzte Frame einer fragmentierten Nachricht ist (
true= FIN-Bit gesetzt). - $length: Länge der Nutzdaten in Bytes.
- $flags: Bitmaske weiterer Frame-Flags.
Beispiele
Eingehende Frames im onMessage-Handler verarbeiten
<?php
$server = new Swoole\WebSocket\Server('0.0.0.0', 9501);
$server->on('open', function (Swoole\WebSocket\Server $server, Swoole\Http\Request $request) {
echo "Neue Verbindung: fd={$request->fd}\n";
});
$server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) {
echo "Empfangen von fd={$frame->fd}\n";
echo "Opcode : {$frame->opcode}\n"; // 1 = Text
echo "FIN : " . ($frame->finish ? 'true' : 'false') . "\n";
echo "Länge : {$frame->length} Bytes\n";
echo "Daten : {$frame->data}\n";
// Nachricht zurückspiegeln
$server->push($frame->fd, 'Echo: ' . $frame->data);
});
$server->on('close', function (Swoole\WebSocket\Server $server, int $fd) {
echo "Verbindung {$fd} geschlossen.\n";
});
$server->start();
Manuell einen Binary-Frame senden
<?php
$server = new Swoole\WebSocket\Server('0.0.0.0', 9501);
$server->on('open', function (Swoole\WebSocket\Server $server, Swoole\Http\Request $request) {
// Binären Frame manuell erzeugen und sofort senden
$frame = new Swoole\WebSocket\Frame();
$frame->fd = $request->fd;
$frame->data = pack('N', 42); // 4-Byte Big-Endian Integer
$frame->opcode = WEBSOCKET_OPCODE_BINARY; // = 2
$frame->finish = true;
$server->push($request->fd, $frame);
echo "Binary-Frame an fd={$request->fd} gesendet.\n";
});
$server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) {
// Ping-Frame erkennen
if ($frame->opcode === WEBSOCKET_OPCODE_PING) {
$pong = new Swoole\WebSocket\Frame();
$pong->opcode = WEBSOCKET_OPCODE_PONG; // = 10
$pong->data = $frame->data;
$server->push($frame->fd, $pong);
}
});
$server->on('close', function (Swoole\WebSocket\Server $server, int $fd) {});
$server->start();
// Wichtig · Fallstricke
Opcodes: Swoole stellt Konstanten wie WEBSOCKET_OPCODE_TEXT (1), WEBSOCKET_OPCODE_BINARY (2), WEBSOCKET_OPCODE_CLOSE (8), WEBSOCKET_OPCODE_PING (9) und WEBSOCKET_OPCODE_PONG (10) bereit – deren Nutzung ist expliziten Integer-Literalen vorzuziehen.
Fragmentierung: Große Nachrichten können über mehrere Frames verteilt werden. Ist $frame->finish gleich false, handelt es sich um einen nicht-finalen Fragment-Frame. Swoole puffert solche Frames standardmäßig und ruft onMessage erst nach dem vollständigen Empfang aller Fragmente auf (sofern open_websocket_close_frame nicht deaktiviert ist).
Sicherheit: Die Nutzdaten in $frame->data stammen direkt vom Client und sind nicht validiert. Eingaben sollten stets geprüft und sanitisiert werden, bevor sie weiterverarbeitet oder an andere Clients weitergeleitet werden.
Verfügbarkeit: Diese Klasse ist nur verfügbar, wenn die Swoole-Erweiterung installiert ist. Sie gehört nicht zum PHP-Kern und ist nicht mit dem nativen php-websockets-Bibliotheken kompatibel.