이번에는 PHP 장기 연결 사용 사례 분석을 가져오겠습니다. PHP 장기 연결 사용 시 주의사항은 무엇인가요?
Long Polling
서버 측에서 연결을 유지하고 데이터가 있을 때까지 즉시 반환하지 않습니다. 이것이 긴 연결 기술의 원칙입니다.
긴 연결 기술의 핵심은 HTTP 요청을 유지하는 것입니다. 그러면 클라이언트는 자동으로 긴 연결 요청을 다시 시작합니다.
그러면 요청을 보류하는 방법은 무엇일까요? 서버 측 코드는 다음과 같습니다
set_time_limit(0); //这句很重要, 不至于运行超时 while (true) { if (hasNewMessage()) { echo json_encode(getNewMessage()); break; } usleep(100000); //避免太过频繁的查询 }
예, 즉시 반환되지 않도록 루프를 통해 요청을 보류하는 것입니다. 그런 다음 클라이언트가 데이터를 처리한 후에만 요청에 응답합니다. , 다시 긴 연결 요청을 시작합니다.
클라이언트 코드는 다음과 같습니다
<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>
간단한 채팅방
긴 연결을 통해 간단한 웹 채팅방을 개발할 수 있습니다
다음으로 redis 웹 채팅방을 통해 간단한 채팅방을 개발하세요
1. 각 클라이언트가 긴 연결을 시작하면 서버 측에 사용자에 해당하는 메시지 대기열이 생성됩니다. 그런 다음 새로운 데이터가 있는지 모니터링하고 데이터를 반환합니다. 처리를 위해 클라이언트에 다시 요청합니다.
2. 각 클라이언트가 메시지를 시작하면 메시지 대기열이 브로드캐스트됩니다.
다음은 코드 조각입니다.
<?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); } } }
긴 연결은 너무 빈번한 폴링을 피합니다. 그러나 서버에는 긴 연결을 유지하기 위한 추가 리소스가 있습니다. 동시성이 클 경우 성능이 이상적이지 않습니다. 클라이언트가
html5 웹소켓 프로토콜을 사용하는 것이 좋습니다. 서버측에서는 swoole을 사용합니다.이 기사의 사례를 읽으신 후 방법을 마스터하셨다고 생각합니다. PHP 중국어 웹사이트의 다른 관련 기사도 주목해 주세요!
추천 도서:PHP 네임스페이스 사용에 대한 자세한 설명
PHP 중국어 도구 클래스 ChineseUtil을 사용하여 한자와 병음을 변환하는 방법 ChineseUtil
위 내용은 PHP 긴 연결 사용 사례 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!