Dans la programmation du réseau PHP, la fonction Socket_Select est l'outil de base pour implémenter le multiplexage (multiplexage d'E / S). Il permet au programme d'écouter plusieurs sockets en même temps, de déterminer les prises lisibles, d'écrit ou d'avoir des exceptions, d'éviter de bloquer et d'attendre, et donc de gérer efficacement les connexions simultanées. Cet article combinera des cas pratiques pour expliquer l'utilisation de Socket_Select et son application dans la programmation réseau PHP.
Socket_Select est utilisé pour surveiller un ensemble de ressources de socket et déterminer quelles prises sont prêtes à lire et à écrire des opérations. Le prototype est le suivant:
int socket_select(array &$read, array &$write, array &$except, ?int $tv_sec, ?int $tv_usec = null)
$ Read : Écoutez s'il est lisible.
$ write : écoutez s'il est écrit ou non
$ sauf : le tableau de douille qui écoute des exceptions
$ tv_sec et $ tv_usec : timeout (secondes et microsecondes)
La fonction bloque jusqu'à ce qu'au moins un socket soit prêt, ou un délai d'expiration, renvoyant le nombre de prises prêtes.
Dans le développement réel du serveur, nous sommes souvent confrontés à la situation où plusieurs connexions clients arrivent en même temps. L'utilisation de blocage Socket_Accept ne peut pas gérer plusieurs connexions en même temps, ce qui peut facilement conduire à des goulots d'étranglement de performances. Via socket_select , nous pouvons:
Écoutez simultanément les connexions du client
Lisez les données dans le temps où la prise a des données et ne bloquera pas le CPU lorsqu'elle est inactive
Mettre en œuvre un modèle efficace axé sur les événements
L'exemple suivant implémente un serveur de salle de chat simple qui prend en charge plusieurs connexions client et diffuse des messages à tout le monde.
<?php
// créerTCP Socket
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($server, "0.0.0.0", 12345);
socket_listen($server);
$clients = [];
echo "Startup de serveur de salle de chat,Écouter le port12345...\n";
while (true) {
// Construisez un tableau d'écoute,Y compris le serveursocketEt tous les clientssocket
$readSockets = $clients;
$readSockets[] = $server;
// utilisersocket_selectAttendre la lisibilitésocket
$write = $except = null;
$numChangedSockets = socket_select($readSockets, $write, $except, 0, 200000);
if ($numChangedSockets === false) {
echo "socket_select Une erreur s'est produite\n";
break;
} elseif ($numChangedSockets > 0) {
// Écoutez une nouvelle connexion
if (in_array($server, $readSockets)) {
$newClient = socket_accept($server);
if ($newClient !== false) {
$clients[] = $newClient;
$welcomeMsg = "Bienvenue dans la salle de chat!\n";
socket_write($newClient, $welcomeMsg, strlen($welcomeMsg));
echo "Rejoignez le nouveau client,Numéro de connexion actuel:" . count($clients) . "\n";
}
// depuisreadSocketsEnlevéserver socket,Empêcher le traitement répété
$key = array_search($server, $readSockets);
unset($readSockets[$key]);
}
// Traiter les messages envoyés par le client
foreach ($readSockets as $sock) {
$data = @socket_read($sock, 2048, PHP_NORMAL_READ);
if ($data === false || $data === '') {
// Le client ferme la connexion
$key = array_search($sock, $clients);
socket_close($sock);
unset($clients[$key]);
echo "Déconnexion du client,Numéro de connexion actuel:" . count($clients) . "\n";
continue;
}
$data = trim($data);
if ($data) {
echo "A reçu un message: $data\n";
// Diffuser des messages à tous les clients
foreach ($clients as $client) {
if ($client != $sock) {
socket_write($client, "Un utilisateur a dit: $data\n");
}
}
}
}
}
}
socket_close($server);
Le serveur crée d'abord une prise TCP, lie le port et écoute la connexion.
Dans la boucle principale, $ readsockets contient toutes les prises clients et les prises d'écoute du serveur.
Appelez Socket_Select pour attendre que toute prise est lisible.
Si le socket serveur est lisible, il existe une nouvelle connexion, acceptée et ajoutée à la liste des clients.
Si le socket client est lisible, lit les données, ferme la connexion si vide, sinon diffuse le message.
Utilisez un délai court non bloquant de 0,2 seconde pour éviter le ralenti du processeur.
Socket_Select est la clé du multiplexage d'E / S multi-connexion, évitant le blocage et l'amélioration des performances du serveur.
Le traitement simultané multi-client peut être facilement implémenté à l'aide de socket_select .
Convient pour les salles de chat, les jeux en ligne, la messagerie instantanée et d'autres scénarios d'application réseau.
Si vous souhaitez connaître des tutoriels et des cas plus détaillés sur la programmation réseau PHP, vous pouvez visiter: http://gitbox.net/php-network-tutorial