国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

PHP長連接實現與使用方法詳解

2024-05-05 00:02:21
字體:
來源:轉載
供稿:網友

本文實例講述了PHP長連接實現與使用方法。分享給大家供大家參考,具體如下:

長連接技術(Long Polling)

在服務器端hold住一個連接, 不立即返回, 直到有數據才返回, 這就是長連接技術的原理

長連接技術的關鍵在于hold住一個HTTP請求, 直到有新數據時才響應請求, 然后客戶端再次自動發起長連接請求.

那怎么樣hold住一個請求呢?服務器端的代碼可能看起來像這樣的

set_time_limit(0); //這句很重要, 不至于運行超時while (true) {  if (hasNewMessage()) {    echo json_encode(getNewMessage());    break;  }  usleep(100000);   //避免太過頻繁的查詢}

沒錯,就是通過循環來實現hold住一個請求, 不至于立即返回. 查詢到有新數據之后才響應請求. 然后客戶端處理數據后,再次發起長連接請求.

客戶端的代碼是像這樣的

<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>

一個簡易的聊天室

通過長連接, 我們可以開發一個簡易的web聊天室

下面, 我們通過redis開發一個簡易的web聊天室

1. 每一個客戶端發起長連接時, 在服務器端生成一個消息隊列, 對應該用戶. 然后監聽有無新數據, 有則返回數據到客戶端進行處理, 并再起發起長連接請求.

2. 每一個客戶端發起消息時, 進行消息隊列的廣播.

下面是代碼片段:

<?phpnamespace 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的websocket協議, 服務器端使用swoole.

有關swoole, 你可以查看官網:https://www.swoole.com/

希望本文所述對大家PHP程序設計有所幫助。


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 甘肃省| 丰城市| 钦州市| 南靖县| 宁波市| 杭锦旗| 哈尔滨市| 织金县| 聂拉木县| 西青区| 刚察县| 砚山县| 滁州市| 澄城县| 轮台县| 海盐县| 彩票| 新民市| 涞水县| 高台县| 波密县| 响水县| 若尔盖县| 巴彦淖尔市| 莎车县| 巢湖市| 呼伦贝尔市| 巴东县| 随州市| 文成县| 临沧市| 三明市| 都安| 闽侯县| 大英县| 房产| 左云县| 齐齐哈尔市| 伊春市| 交城县| 庆云县|