Ich versuche, die Funktion stream_socket_client () von PHP nicht blockierend (asynchron) zu verwenden. Die Dokumentation auf der PHP-Website zeigt an, dass das Optionsfeld STREAM_CLIENT_ASYNC_CONNECT dies aktivieren sollte. Allerdings der folgende Code ...
%Vor%Gibt Folgendes aus:
%Vor%Offensichtlich blockiert die Funktion (auch unterstützt durch die Tatsache, dass das Weglassen des STREAM_CLIENT_ASYC_CONNECT-Flags die Skriptausgabe "Gesamtzeit" nicht sinnvoll verändert.
Irgendwelche Ideen, warum dies passieren könnte, und wie man einen nicht-blockierenden Verbindungsversuch erzwingt?
Es ist unmöglich, die ssl: // Familie von Stream-Wrappern zu verwenden, um zu dieser Zeit nicht blockierende Verbindungen in PHP herzustellen, und der Grund ist einfach:
Um einen SSL / TLS-Handshake aushandeln zu können, müssen Sie Daten senden und empfangen.
Sie können solche Informationen nicht einfach innerhalb einer einzigen Operation duplexieren (z. B. was die Stream-Wrapper tun), ohne die Skriptausführung zu blockieren. Und da PHP ursprünglich dafür entworfen wurde, in streng synchronen Umgebungen zu arbeiten (d. H. Die blockierenden Web-SAPIs, wo jede Anfrage ihren eigenen Prozess hat), ist dieses Blockierungsverhalten die natürliche Sache.
Als Ergebnis wird der ssl: // Stream-Wrapper nicht so funktionieren, wie Sie es möchten, selbst wenn Sie den STREAM_CLIENT_ASYNC_CONNECT-Flag setzen. Es ist jedoch immer noch möglich, die Stream-Verschlüsselungsfunktionen von PHP in Ihren nicht blockierenden Socket-Operationen zu verwenden.
Die SSL / TLS-Protokolle werden über dem zugrunde liegenden Datentransportprotokoll ausgeführt. Dies bedeutet, dass wir nur die Verschlüsselungsprotokolle nach TCP / UDP / etc aktivieren. Verbindung ist hergestellt. Als Ergebnis können wir uns zunächst mit dem asynchronen Flag STREAM_CLIENT_ASYC_CONNECT mit dem entfernten Teilnehmer verbinden und anschließend Krypto auf dem (jetzt verbundenen) Socket aktivieren, indem wir stream_socket_enable_crypto()
.
In diesem Beispiel wird davon ausgegangen, dass Sie verstehen, wie stream_select()
(oder eine entsprechende Deskriptorbenachrichtigungs-Lib, die nicht blockierend mit Sockets arbeiten soll) verwendet wird. Es gibt keine Behandlung für mögliche Socket-Fehler.
Es ist sehr wichtig, die Gleichheit von ===
zu verwenden, wenn Sie die Ergebnisse aus unseren Crypto-Aktivierungsaufrufen überprüfen. Wie im entsprechenden Handbuch erwähnt:
Gibt bei Erfolg TRUE zurück, FALSE, wenn die Aushandlung fehlgeschlagen ist, oder 0, wenn nicht genügend Daten vorhanden sind, und Sie sollten es erneut versuchen (nur für nicht blockierende Sockets).
Wenn wir ===
nicht verwenden, können wir nicht zwischen false
und 0
unterscheiden.