Die persistente Verbindung ist eine sehr häufige Anforderung beim Erstellen von Socket-basierten Server- oder Client-Programmen mithilfe von PHP. Insbesondere in Szenarien wie Instant Messaging, Online -Spielen oder Datenschubs hat der Steckdose lange Zeit und ständig gesäumt, wenn die Leistung und die Benutzererfahrung ständig ausgewirkt.
In diesem Szenario ist die rationale Verwendung von Socket_Clear_error () ein Schlüsselmittel, um die Verbindung stabil zu halten. In diesem Artikel wird eingehend untersucht, wie er verwendet wird, und kombiniert einige praktische Beispiele, um zu veranschaulichen, wie die Unterbrechungen von Verbindungen aufgrund nicht erachter Fehler vermieden werden.
Socket_Clear_error () ist eine von PHP bereitgestellte Socket -Betriebsfunktion, um Fehlerinformationen zu löschen, die einer angegebenen Socket zugeordnet sind. Die Funktionssignatur ist wie folgt:
void socket_clear_error ([ resource $socket ] )
Es kann in einer bestimmten Steckdose oder global verwendet werden. Wenn in einer Socket -Operation ein Fehler auftritt, wird die Fehlermeldung gespeichert. Wenn diese Fehler nicht rechtzeitig gelöscht werden, kann das nächste Mal, wenn die Socket -Funktion aufgerufen wird, das Verhalten beeinflussen und sogar dazu führen, dass die Verbindung getrennt wird.
Es gibt viele Gründe für eine Trennung bei der Verwendung langer Verbindungen, wie z. B.:
Netzwerk Jitter;
Der Kunde schließt die Verbindung;
Der interne Verarbeitungsfehler Server wird nicht erfasst.
Fehlerstapel wird nicht gelöscht.
Der letzte ist der Schwerpunkt unseres Artikels. Auch wenn es sich um einen leichten nicht tödlichen Fehler handelt, können Sie beim nächsten Mal nicht über Socket_Write () und socket_read () abnormal zurückkehren oder einen Interrupt auslösen, da der "Fehlerzustand" erkannt wird.
Hier finden Sie ein typisches PHP-Socket-Server-Code-Code-Snippet, das Client-Anforderungen übernimmt und lange Verbindungen verwaltet:
$host = '0.0.0.0';
$port = 9000;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $host, $port);
socket_listen($socket);
$clients = [];
while (true) {
$read = $clients;
$read[] = $socket;
$write = $except = null;
socket_select($read, $write, $except, 0, 200000); // Nicht blockierende
if (in_array($socket, $read)) {
$client = socket_accept($socket);
$clients[] = $client;
socket_clear_error($client); // Löschen Sie den Fehlerstatus der neuen Verbindung
}
foreach ($clients as $key => $client) {
$data = @socket_read($client, 1024, PHP_NORMAL_READ);
if ($data === false) {
$error = socket_last_error($client);
if ($error !== 0) {
echo "Socket error: " . socket_strerror($error) . "\n";
socket_clear_error($client);
}
continue;
}
$data = trim($data);
if ($data == 'quit') {
socket_close($client);
unset($clients[$key]);
continue;
}
$response = "Server received: $data\n";
@socket_write($client, $response, strlen($response));
socket_clear_error($client); // Löschen Sie Fehler nach jeder Kommunikation
}
}
Dieser Code zeigt mehrere Schlüsselstrategien:
Verwenden Sie jedes Mal, wenn eine Clientverbindung empfangen wird, Socket_Clear_error (), um den Status sofort zu löschen.
Löschen Sie mögliche Fehler nach jedem Lesen oder Schreibvorgang;
Bei nicht tödlichen Fehlern (z. B. vorübergehende Netzwerkausfälle) trennen Sie nicht sofort, sondern versuchen Sie, die Verarbeitung zu löschen und fortzusetzen.
Zusätzlich zum Löschen von Fehlern ist es auch der Schlüssel, die Verbindung ständig zu halten, sondern auch das rationale Entwerfen des "Heartbeat -Pakets". Mit dem Herzbeatmechanismus kann der Client ein leichtes Datenpaket zu einem festen Zeitpunkt an den Server senden. Wenn der Herzschlag nach einer bestimmten Zeit nicht erhalten wird, kann die Verbindung automatisch geschlossen werden.
// Vereinfachte Version des Heartbeat -Antwortbeispiels
if ($data == 'ping') {
@socket_write($client, "pong\n");
socket_clear_error($client);
}
Dies kann den Unterschied zwischen "real gebrochener Linie" und "Fehleinschätzung" mit socket_clear_error () besser erkennen.
Wenn der Fehler nicht lange gelöscht wird, wird auch die sogenannte "Zombie-Verbindung" verursacht, dh das Socket-Objekt ist noch vorhanden, ist jedoch bereits in einem ungültigen Zustand. Hier finden Sie eine Möglichkeit, den Status aller Kunden regelmäßig zu überprüfen: