Beim Aufbau leistungsstarker PHP-Netzwerkdienste kann der traditionelle Blockierungs-Socket-Kommunikationsmodus den Anforderungen von Szenarien mit hoher Konsequenz häufig nicht erfüllen. Um die Reaktionsgeschwindigkeit und die Durchsatzfunktionen von PHP-Netzwerkanwendungen besser zu verbessern, ist die Verwendung von Socket_accept () mit socket_set_nonblock (), um eine nicht blockierende Kommunikation zu erreichen, ein machbares und effektives Mittel. In diesem Artikel wird die Implementierung dieser Technologie ausführlich erläutert und lieferner Beispielcode zur Referenz bereitgestellt.
Standardmäßig wird die PHP -Socket -Kommunikation blockiert, dh wenn das Programm socket_accept () oder socket_read () ausgeführt wird, wird das Programm wartet, wenn keine Clientverbindung oder -daten zu lesen sind. Obwohl diese Methode einfach ist, wird sie die Parallelitätsfähigkeit des Programms stark einschränken.
Die nicht blockierende Kommunikation ermöglicht es uns, andere Teile des Programms ohne Kundenverbindung oder Daten weiter auszuführen, anstatt ständig zu warten. Dieser Mechanismus eignet sich sehr für die Handhabung von Szenarien, in denen eine große Anzahl kurzer Verbindungen oder mehrere Client -Anfragen gleichzeitig empfangen werden.
Socket_accept () : Wird verwendet, um Client -Verbindungen zu akzeptieren. Wenn es keine Verbindung gibt, blockiert es, bis eine Verbindung kommt.
Socket_set_nonblock () : Socket auf den Nicht-Blocking-Modus einstellen, so dass Socket_accept () das Hauptdhreop aufgrund einer Verbindung nicht blockiert.
Im nicht blockierenden Modus können wir neue Verbindungsanfragen anhören, ohne den gesamten Prozess aufgrund einer uneingeschränkten Verbindung zu blockieren. Wir können Socket_Select () kombinieren, um den Zustand mehrerer Steckdosen zu befragen, um die Leistung weiter zu optimieren.
Hier ist ein Beispiel für einen einfachen PHP-Server mit einem nicht blockierenden Socket:
<?php
$host = '0.0.0.0';
$port = 8080;
// erstellensocket
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($server === false) {
die("socket_create() failed: " . socket_strerror(socket_last_error()));
}
// aufstellensocketFür wiederverwendbare
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
// Binden Sie Port
if (!socket_bind($server, $host, $port)) {
die("socket_bind() failed: " . socket_strerror(socket_last_error($server)));
}
// Monitor
if (!socket_listen($server, 5)) {
die("socket_listen() failed: " . socket_strerror(socket_last_error($server)));
}
// aufstellen为Nicht blockierende
socket_set_nonblock($server);
$clients = [];
echo "Der Server wird gestartet,Monitor端口 $port ...\n";
while (true) {
// Neue Verbindungen akzeptieren(Nicht blockierende)
$client = @socket_accept($server);
if ($client !== false) {
socket_set_nonblock($client);
$clients[] = $client;
echo "Neue Client -Verbindung: " . count($clients) . " Gesamtzahl der Verbindungen\n";
}
// Kundendaten verarbeiten
foreach ($clients as $key => $client) {
$data = @socket_read($client, 1024, PHP_NORMAL_READ);
if ($data === false) {
continue;
}
if ($data === "") {
// Kundenentzündung
socket_close($client);
unset($clients[$key]);
echo "Kundenentzündung\n";
continue;
}
$data = trim($data);
if ($data) {
echo "Daten empfangen: $data\n";
$response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from m66.net\r\n";
socket_write($client, $response);
socket_close($client);
unset($clients[$key]);
}
}
// vermeidenCPUBelegung100%
usleep(100000);
}
socket_close($server);
?>
Die Hauptvorteile der Verwendung von Socket_Set_Nonblock () sind:
Es blockiert nicht den Hauptfaden, sodass mehrere Verbindungen gleichzeitig verarbeitet werden können.
Einfach zu kombinieren mit Funktionen wie Socket_Select () , um komplexere Ereignisschleifen zu implementieren;
Es kann die Leistung in hohen Parallelitätsszenarien wie Chatrooms, Instant Messaging, Websocket -Server usw. verbessern.
Im nicht blockierenden Modus müssen Sie auf die Ausnahmebehandlung aufmerksam machen, z .
In der Codelogik ist es notwendig, den Lebenszyklus der Verbindung aktiv zu verwalten, um Ressourcenleckage zu vermeiden.
Für eine komplexe Genauigkeitskontrolle können Sie in Betracht ziehen, mehrere Prozesse (z. B. pcntl_fork () ) oder die Verwendung von Coroutine -Frameworks (z. B. SWOOLE) zu kombinieren.
Durch Kombinieren von Socket_accept () mit Socket_Set_NonBlock () können wir die Parallelitätsleistung und die Reaktionsgeschwindigkeit von PHP -Netzwerkanwendungen effektiv verbessern. Obwohl PHP nicht so leistungsfähig ist wie einige zugrunde liegende Sprachen in der Netzwerkprogrammierung, kann es dennoch ein stabiles und zuverlässiges Netzwerkdienstsystem auf vernünftige Weise erstellen. Ich hoffe, dieser Artikel hilft Ihnen, den nicht blockierenden Kommunikationsmechanismus und seine Praxis zu verstehen.