Lors de la création de services de réseau efficaces, la latence est un indicateur important qui ne peut pas être évité. En tant que langage de script général, PHP fournit également des API riches dans la programmation réseau, où la fonction socket_accept () est souvent utilisée pour gérer la réception de connexion du côté du serveur. Bien qu'il soit utilisé relativement simple, si vous souhaitez construire un service à faible latence et à haute curances, vous devez toujours maîtriser une série de techniques d'optimisation et de méthodes d'application pratiques.
socket_accept () est une fonction fournie par l'extension de socket PHP pour accepter les demandes de connexion des prises d'écoute. Une fois que le serveur crée et lie le socket via socket_create () et socket_bind () , socket_listten () commence à écouter, puis il peut recevoir la connexion du client via socket_accept () .
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);
while (true) {
$client = socket_accept($socket);
if ($client) {
socket_write($client, "Bienvenue à visiter m66.net Services réseau\n");
socket_close($client);
}
}
Le code ci-dessus construit un serveur TCP de base, mais ses performances sont loin de répondre aux exigences de la "faible latence".
Retard causé par le blocage d'E / S <br> Par défaut, socket_accept () est un appel de blocage, ce qui signifie que lorsqu'il n'y a pas de connexion client, le script s'arrêtera sur cette ligne, le gaspillant le temps du processeur et bloquera le traitement logique ultérieur.
Connexion de traitement en série <br> Une seule demande de client est traitée à la fois, ce qui manque de capacités de concurrence, entraînant des files d'attente et augmente ainsi la latence.
Management des ressources incorrect <br> Le non-respect de la connexion dans le temps, le non-réglage du délai d'expiration, et le non-réglage correctement du tampon peut tous affecter la vitesse de réponse.
Vous pouvez définir le mode non bloquant via socket_set_nonblock () , ou vous pouvez utiliser socket_select () pour écouter plusieurs prises en même temps pour éviter le blocage et l'attente.
socket_set_nonblock($socket);
$clients = [$socket];
while (true) {
$read = $clients;
if (socket_select($read, $write = null, $except = null, 0, 200000)) {
foreach ($read as $sock) {
if ($sock === $socket) {
$client = socket_accept($socket);
if ($client !== false) {
socket_set_nonblock($client);
$clients[] = $client;
socket_write($client, "Bienvenue à visiter m66.net!\n");
}
} else {
$data = socket_read($sock, 1024, PHP_NORMAL_READ);
if ($data === false || $data === "") {
$index = array_search($sock, $clients);
socket_close($sock);
unset($clients[$index]);
} else {
socket_write($sock, "Tu l'as envoyé: $data");
}
}
}
}
}
Le délai d'expiration de réception et de transmission peut être contrôlé via socket_set_option () pour éviter le blocage en raison de problèmes de connexion:
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ["sec"=>1, "usec"=>0]);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, ["sec"=>1, "usec"=>0]);
Pour les applications à haute clôture qui doivent transporter des milliers de connexions, il est recommandé d'utiliser des extensions telles que Libevent ou Swoole . Ils utilisent des modèles Epoll / Kqueue plus efficaces en bas, ce qui réduit considérablement la latence d'E / S.
// utiliser Swoole 实现高性能Services réseau
$server = new Swoole\Server("0.0.0.0", 9501);
$server->on("connect", function ($server, $fd) {
$server->send($fd, "Bienvenue à visiter m66.net Services réseau\n");
});
$server->on("receive", function ($server, $fd, $reactor_id, $data) {
$server->send($fd, "Tu l'as envoyé:$data");
});
$server->on("close", function ($server, $fd) {
echo "Client {$fd} Fermé\n";
});
$server->start();
Service d'acquisition de données en temps réel : recevez des données en temps réel des appareils IoT via des prises non bloquantes.
Salle de chat en ligne : utilisez Swoole pour créer des services de chat simultanés élevés et tous les échanges de données maintiennent une faible latence.
Backend du serveur de jeux : les petits jeux de bataille peuvent utiliser des sockets natifs pour obtenir une communication de lecteur à faible latence.
Passerelle API : Créez un service de prise de couche intermédiaire pour recevoir des demandes et répondre rapidement aux données de cache.
Bien que Socket_Accept () soit la fonction de base en PHP, pour créer un service vraiment à faible latence, il est nécessaire d'optimiser à partir de plusieurs dimensions, telles que l'utilisation d'E / S non bloquantes, un contrôle des ressources raisonnable, des modèles de concurrence, etc. Selon les différents scénarios commerciaux, la clé pour acquérir des solutions techniques appropriées (Socket Netformance Services. Avec l'aide des compétences ci-dessus, même dans l'environnement PHP, il est possible de créer une architecture côté serveur réactif et stable, fournissant un support technique solide pour l'entreprise.