Analyse de cas d'utilisation de connexion longue PHP

php中世界最好的语言
Libérer: 2023-03-26 16:40:01
original
2190 Les gens l'ont consulté

Cette fois, je vais vous présenter une analyse de cas d'utilisation d'une connexion longue PHP. Quelles sont les précautions lors de l'utilisation d'une connexion longue PHP. Voici des cas pratiques, jetons un coup d'oeil.

Interrogation longue

Maintenez une connexion côté serveur et ne revenez pas immédiatement jusqu'à ce qu'il y ait des données Retour, c'est. le principe de la technologie de connexion longue

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

Comment retenir une demande ? Le code côté serveur peut ressembler à ceci

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

Oui, il est implémenté via une boucle pour conserver une demande afin de ne pas revenir immédiatement. La demande ne recevra une réponse qu'après l'interrogation de nouvelles données. Ensuite, le client le traite. Après avoir reçu les données, lancez à nouveau une longue demande de connexion

Le code client est comme ça

<script type="text/javascript">
  (function longPolling() {
    $.ajax({
      'url': 'server.php',
      'data': data,
      'dataType': 'json',
      'success': function(data) {
        processData(data);
        longPolling();
      },
      'error': function(data) {
        longPolling();
      }
    });
  })();
</script>
Copier après la connexion

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. une longue connexion Lorsque, 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. Chaque client Lorsqu'un message est initié, la file d'attente des messages est diffusée

Ce qui suit est un extrait de code :

Une longue connexion évite des interrogations trop fréquentes. Le serveur dispose également de ressources supplémentaires pour maintenir une longue connexion. Les performances ne sont pas idéales lorsqu'il y a une grande concurrence. Vous pouvez envisager d'utiliser
<?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['type']) {
      case 'unicast':   //单播
        $this->unicast($data['target'], $data['data'], $data['resource']);
        break;
      case 'multicast':    //组播
        foreach ($data['target'] as $target) {
          $this->unicast($target, $data['data'], $data['resource']);
        }
        break;
      case 'broadcast':    //广播
        foreach ($this->redisQueue->setQueueName('connections') as $target) {
          $this->unicast($target, $data['data'], $data['resource']);
        }
        break;
    }
    $this->fire('message');
  }
  public function unicast($target, $message, $resource = 'system')
  {
    $redis_queue = new RedisQueue();
    $redis_queue->setQueueName($target)->push($resource . ':' . $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('action') == 'getMessage') {
        if ($this->hasMessage($data->get('target'))) {
          $this->response->setData([
            'state' => 'ok',
            'message' => '获取成功',
            'data' => $this->getMessage($data->get('target'))
          ]);
          $this->response->send();
          break;
        }
      } elseif ($data->get('action') == 'connect') {
        $exist = false;
        foreach ($this->redisQueue->setQueueName('connections') as $connection) {
          if ($connection == $data->get('data')) {
            $exist = true;
          }
        }
        if (! $exist) {
          $this->redisQueue->setQueueName('connections')->push($data->get('data'));
        }
        $this->fire('connect');
        break;
      }
      usleep(100000);
    }
  }
}
Copier après la connexion

dans de petites applications. Le protocole websocket de

html5 et le côté serveur utilisent swoole

Je crois qu'après avoir lu le cas dans cet article, vous maîtrisez la méthode. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le. Site Web chinois PHP !

Lecture recommandée :

Explication détaillée de l'utilisation de l'espace de noms PHP


Comment convertir les caractères chinois et le pinyin avec PHP Classe d'outils chinois ChineseUtil

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal