Maison  >  Article  >  développement back-end  >  Comment implémenter une connexion longue dans un socket php

Comment implémenter une connexion longue dans un socket php

伊谢尔伦
伊谢尔伦original
2018-05-14 17:13:3825439parcourir

Qu'est-ce qu'une longue connexion ?

Les amis auraient dû voir de nombreux outils de chat en ligne et outils de chat en ligne sur le Web. Il existe une fonction familière à l'école. Si quelqu'un vous répond, une invite apparaîtra immédiatement sur le site Web. Vous n'avez pas actualisé la page pour le moment. Si un nouvel e-mail est reçu dans la boîte aux lettres, le site Web vous le rappellera immédiatement, même si vous n'avez jamais actualisé la page Web. En parlant de cela, tout le monde doit être familier avec cela, qui consiste à réutiliser un lien pour une interaction continue des données. De nos jours, de nombreux scénarios commerciaux sur Internet nécessitent la prise en charge de longues connexions, telles que les jeux, les chats, la transmission d'informations, etc. De nombreuses fonctions similaires sont indissociables des longues connexions. Le chapitre précédent a présenté la communication par socket php. Ce chapitre présentera la connexion longue par socket php.

Connexions longues et liens courts

Les connexions courtes demandent généralement des données à un seul élément. Le serveur ne peut pas activement « pousser » les données vers le client, mais avec une longue durée. connexion Bien meilleure, en utilisant la combinaison des technologies back-end et front-end, la fonction « pousser les informations » du serveur peut être réalisée s'il y a une mise à jour dans la base de données, le programme back-end peut « extraire » les données immédiatement. , au lieu de le demander à plusieurs reprises, la connexion est établie et déconnectée plusieurs fois.

Il a probablement les explications suivantes :

  1. La connexion dite longue fait référence au maintien de la connexion, qu'elle soit utilisée ou non après l'établissement d'une connexion SOCKET, mais la sécurité est médiocre ; la connexion dite courte fait référence à l'établissement d'une connexion SOCKET et à la déconnexion immédiatement après l'envoi et la réception de données. Généralement, les banques utilisent des connexions courtes

  2. Les connexions longues font référence. maintenir la connexion dans la communication basée sur TCP, que les données soient actuellement envoyées ou reçues. La connexion courte signifie que la connexion n'est établie que lorsqu'il y a une transmission de données et que la connexion est fermée une fois la communication/transmission client-serveur des données terminée.

  3. Méthodes de communication
    Il existe deux méthodes de connexion entre chaque élément du réseau : la connexion longue et la connexion courte. La connexion dite longue signifie que plusieurs paquets de données peuvent être envoyés en continu sur une connexion TCP. Pendant la période de maintien de la connexion TCP, si aucun paquet de données n'est envoyé, les deux parties doivent envoyer des paquets de détection pour maintenir la connexion. Une connexion courte signifie que lorsque les parties communicantes échangent des données, une connexion TCP est établie une fois les données envoyées, la connexion TCP est déconnectée, c'est-à-dire que chaque connexion TCP termine uniquement l'envoi d'une paire de messages CMPP.
    À ce stade, les ISMG doivent utiliser des méthodes de communication à long terme. Il est recommandé d'utiliser des méthodes de communication à long terme entre les SP et les ISMG.

  4. Connexion courte : par exemple, HTTP se connecte, demande et se ferme uniquement. Le temps de traitement est court. Si le serveur ne reçoit pas la demande dans un délai donné, il peut se fermer. la connexion. Connexion longue : Certains services nécessitent des connexions à long terme au serveur, comme CMPP, et nécessitent généralement une maintenance en ligne par vous-même.

Implémentation d'une connexion longue socket

Chaque fois que nous accédons à un script PHP, nous attendons que tous les scripts PHP soient exécutés. Si nous avons besoin qu'un script s'exécute en continu, nous devons alors utiliser une connexion longue PHP pour atteindre l'objectif de l'opération.

Si vous voulez jouer avec des connexions longues, vous devez vous occuper des sockets. L'encapsulation des sockets est naturellement indispensable. Vous trouverez ci-dessous le code pour effectuer une longue connexion socket.

L'exemple de code est le suivant :

<?php
$sfd = socket_create(AF_INET, SOCK_STREAM, 0);  
socket_bind($sfd, "0.0.0.0", 1234);  
socket_listen($sfd, 511);  
socket_set_option($sfd, SOL_SOCKET, SO_REUSEADDR, 1);  
socket_set_nonblock($sfd);  
$rfds = array($sfd);  
$wfds = array(); 
 
do{  
    $rs = $rfds;  
    $ws = $wfds;  
    $es = array();  
    $ret = socket_select($rs, $ws, $es, 3);        
    //读取事件 
    foreach($rs as $fd){  
        if($fd == $sfd){ 
           $cfd = socket_accept($sfd);  
           socket_set_nonblock($cfd);  
            $rfds[] = $cfd;  
            echo "new client coming, fd=$cfd\n";  
        }else{  
            $msg = socket_read($fd, 1024); 
 
            if($msg <= 0){  
                //close  
            }else{                 
                echo "on message, fd=$fd data=$msg\n";  
            }  
        }  
    } 
  
    //写入事件 
    foreach($ws as $fd){  
        socket_write($fd, ........);  
    }       
}while(true);
?>

Ce qui suit améliorera l'efficacité :

<?php
$sfd = stream_socket_server (&#39;tcp://0.0.0.0:1234&#39;, $errno, $errstr);  
stream_set_blocking($sfd, 0);  
$base = event_base_new();  
$event = event_new();  
event_set($event, $sfd, EV_READ | EV_PERSIST, &#39;ev_accept&#39;, $base);  
event_base_set($event, $base);  
event_add($event);  
event_base_loop($base); 
 
function ev_accept($socket, $flag, $base)  
{  
    $connection = stream_socket_accept($socket);  
    stream_set_blocking($connection, 0);  
    $buffer = event_buffer_new($connection, &#39;ev_read&#39;, NULL, &#39;ev_error&#39;,  $connection);      
    event_buffer_base_set($buffer, $base);  
    event_buffer_timeout_set($buffer, 30, 30);  
    event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);  
    event_buffer_priority_set($buffer, 10);  
    event_buffer_enable($buffer, EV_READ | EV_PERSIST);  
} 
 
function ev_error($buffer, $error, $connection)  
{  
    event_buffer_disable($buffer, EV_READ | EV_WRITE);                  
    event_buffer_free($buffer);                  
    fclose($connection);                  
} 
 
function ev_read($buffer, $connection)  
{  
    $read = event_buffer_read($buffer, 256);  
    //do something....  
}
?>

À mesure que le nombre de personnes augmente et que la concurrence augmente, un seul processus ne peut plus répondre à la demande. Il existe des extensions et des bibliothèques prêtes à l'emploi pour résoudre ce problème, telles que : swoole, workerman, etc. Cependant, lorsque nous utilisons PHP pour développer le Web, nous n'utilisons pas de bibliothèques liées au serveur Web pour le développement, n'est-ce pas ? Nous faisons juste un simple écho. Ces choses compliquées sont toutes confiées à nginx ou apache, et ils prennent les devants sans hésitation, afin que nous puissions nous concentrer sur l'écriture de la logique. L'écriture de services socket n'est pas plus avancée que l'écriture de services Web. Ils codent et remplissent toutes les exigences. La couche de communication est fixe, mais l'une est complétée par nginx et l'autre est complétée par vous-même. . Mais maintenant, vous n'avez plus besoin de le compléter vous-même. Une solution similaire à nginx+fpm, fooking+fpm=php longue connexion, la passerelle est utilisée pour acheminer la connexion et le routeur est utilisé pour transférer les messages.

Le code est le suivant :

<?php
$sid = $_SERVER[&#39;SESSIONID&#39;];//这是sessionid  
$data = file_get_contents("php://input");//这样就能拿到请求内容了  
//想要返回消息只需要两步  
header(&#39;Content-Length: 11&#39;);//返回给客户端字节数  
echo "hello world";  
//想要给别的用户发消息  
include &#39;api.php&#39;;  
$router = new RouterClient(&#39;router host&#39;, &#39;router port&#39;);  
$router->sendMsg(用户sessionid, "fuck you");  
//想要给所有人要消息  
$router->sendAllMsg("fuck all");  
//想给指定组发消息(类似redis的pub/sub)  
$router->publish("channel name", "fuck all");
?>

[Tutoriels associés recommandés]

1. "php.cn Dugu Jiubian ( 4) - Tutoriel vidéo PHP

2 Un ensemble complet de tutoriels sur la programmation PHP de l'entrée à la maîtrise

.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn