Maison >développement back-end >tutoriel php >PHP implémente une méthode de connexion longue
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({ 'url': 'server.php', 'data': data, 'dataType': 'json', 'success': function(data) { processData(data); longPolling(); }, 'error': function(data) { longPolling(); } }); })();</script>
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
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. .
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['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); } } }
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!