Maison  >  Article  >  développement back-end  >  PHP implémente une méthode de connexion longue

PHP implémente une méthode de connexion longue

小云云
小云云original
2018-03-21 11:50:004611parcourir

Maintenez une connexion côté serveur et ne revenez pas immédiatement. Elle ne reviendra pas tant qu'il n'y aura pas de données. C'est le principe de la technologie des connexions longues. Cet article partage principalement avec vous la méthode d'implémentation des connexions longues en PHP, en espérant. pour aider tout le monde.

La clé de la technologie de connexion longue est de suspendre une requête HTTP et de ne pas répondre à la demande jusqu'à ce qu'il y ait de nouvelles données. Ensuite, le client lance à nouveau automatiquement une demande de connexion longue.

Comment conserver. une demande ? Du drap de laine ? Le code côté serveur peut ressembler à ceci

set_time_limit(0);  //这句很重要, 不至于运行超时while (true) 
、{    if (hasNewMessage()) 
{        echo json_encode(getNewMessage());        break;
    }
    usleep(100000);      //避免太过频繁的查询}


Oui, il s'agit de maintenir une requête dans une boucle, afin de ne pas revenir immédiatement. Ce n'est qu'alors que la demande répond. Ensuite, une fois que le client a traité les données, il lance à nouveau une longue demande de connexion.

Le code client est comme ceci

<script type="text/javascript">
    (function longPolling() {
        $.ajax({            &#39;url&#39;: &#39;server.php&#39;,            &#39;data&#39;: data,            &#39;dataType&#39;: &#39;json&#39;,            &#39;success&#39;: function(data) {
                processData(data);
                longPolling();
            },            &#39;error&#39;: function(data) {
                longPolling();
            }
        });
    })();</script>

Une simple salle de discussion

Grâce à de longues connexions, nous pouvons développer une salle de discussion Web simple

Ensuite, nous développons une salle de discussion Web simple via Redis

  1. Lorsque chaque client initie une longue connexion, une file d'attente de messages est générée côté serveur, correspondant à l'utilisateur, puis il surveille s'il y a de nouvelles données, renvoie les données au client pour traitement et lance à nouveau une longue demande de connexion. .

  2. Lorsque chaque client lance un message, il diffuse la file d'attente des messages.

Ce qui suit est un extrait de code :

<?php namespace church\LongPolling;use Closure;use church\LongPolling\Queue\RedisQueue;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\JsonResponse;class Server{
    public $event = [];    public $redisQueue = null;    public $request = null;    public $response = null;    public function __construct()
    {
        $this->redisQueue = new RedisQueue();        $this->request = Request::createFromGlobals();        $this->response = new JsonResponse();
    }    public function on($event, Closure $closure)
    {
        if (is_callable($closure)) {            $this->event[$event][] = $closure;
        }
    }    public function fire($event)
    {
        if (isset($this->event[$event])) {            foreach ($this->event[$event] as $callback) {
                call_user_func($callback, $this);
            }
        }
    }    public function sendMessage($data)
    {
        switch ($data[&#39;type&#39;]) {            case &#39;unicast&#39;:     //单播
                $this->unicast($data[&#39;target&#39;], $data[&#39;data&#39;], $data[&#39;resource&#39;]);                break;            case &#39;multicast&#39;:       //组播
                foreach ($data[&#39;target&#39;] as $target) {                    $this->unicast($target, $data[&#39;data&#39;], $data[&#39;resource&#39;]);
                }                break;            case &#39;broadcast&#39;:       //广播
                foreach ($this->redisQueue->setQueueName(&#39;connections&#39;) as $target) {                    $this->unicast($target, $data[&#39;data&#39;], $data[&#39;resource&#39;]);
                }                break;
        }        $this->fire(&#39;message&#39;);
    }    public function unicast($target, $message, $resource = &#39;system&#39;)
    {
        $redis_queue = new RedisQueue();        $redis_queue->setQueueName($target)->push($resource . &#39;:&#39; . $message);
    }    public function getMessage($target)
    {
        return $this->redisQueue->setQueueName($target)->pop();
    }    public function hasMessage($target)
    {
        return count($this->redisQueue->setQueueName($target));
    }    public function run()
    {
        $data = $this->request->request;        while (true) {            if ($data->get(&#39;action&#39;) == &#39;getMessage&#39;) {                if ($this->hasMessage($data->get(&#39;target&#39;))) {                    $this->response->setData([                        &#39;state&#39; => &#39;ok&#39;,                        &#39;message&#39; => &#39;获取成功&#39;,                        &#39;data&#39; => $this->getMessage($data->get(&#39;target&#39;))
                    ]);                    $this->response->send();                    break;
                }
            } elseif ($data->get(&#39;action&#39;) == &#39;connect&#39;) {                $exist = false;                foreach ($this->redisQueue->setQueueName(&#39;connections&#39;) as $connection) {                    if ($connection == $data->get(&#39;data&#39;)) {                        $exist = true;
                    }
                }                if (! $exist) {                    $this->redisQueue->setQueueName(&#39;connections&#39;)->push($data->get(&#39;data&#39;));   
                }               
                $this->fire(&#39;connect&#39;);                break;
            }
            usleep(100000);
        }
    }
}

La source a été Le code est open source sur github

Une version web simple du salon de discussion développée sur la base de connexions longues. Les connexions longues évitent cependant les interrogations trop fréquentes. Le serveur consomme également des ressources supplémentaires. Les performances ne sont pas idéales en cas de concurrence importante. Il peut être envisagé pour une utilisation dans de petites applications. Il est plus recommandé que le client utilise le protocole websocket html5 et que le serveur utilise swoole.

Recommandations associées :

Comment implémenter des connexions longues dans un socket php

Une brève analyse des principes des connexions http longues et des connexions courtes

Implémentation des connexions longues en PHP

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