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

首頁 > 編程 > PHP > 正文

php socket如何實(shí)現(xiàn)長連接

2020-03-22 18:58:17
字體:
供稿:網(wǎng)友
長連接是什么?

朋友們應(yīng)該都見過很多在線聊天工具和網(wǎng)頁在線聊天的工具。學(xué)校內(nèi)有一種熟悉的功能,如果有人回復(fù)你了,網(wǎng)站會(huì)馬上出現(xiàn)提示,此時(shí)你并沒有刷新頁面;Gmail也有此功能,如果郵箱里收到了新的郵件,網(wǎng)站會(huì)馬上提醒你,即使你的網(wǎng)頁一直未刷新過。說到這里大家肯定不陌生,就是復(fù)用一個(gè)鏈接持續(xù)不斷的進(jìn)行數(shù)據(jù)交互。在現(xiàn)下很多互聯(lián)網(wǎng)業(yè)務(wù)場景都需要長連接的支持,比如:游戲、聊天、信息推送等等等,這么多類似的功能都離不開長連接。前一章節(jié)介紹了php socket通信,本章來介紹一下php socket長連接。

長連接和短鏈接

短連接一般都是單項(xiàng)請(qǐng)求數(shù)據(jù),服務(wù)器不能主動(dòng)把數(shù)據(jù)“推”想客戶端,但有了長連接就好多了,利用后端與前端的技術(shù)組合起來,可以實(shí)現(xiàn)服務(wù)器的“推送信息”功能,如果數(shù)據(jù)庫里面有更新,后端程序可以立即把數(shù)據(jù)“推送出來”,而不要多次反復(fù)請(qǐng)求,多次建立連接,多次斷開。

其大概有如下的幾種解釋:

  1. 所謂長連接指建立SOCKET連接后不管是否使用都保持連接,但安全性較差;所謂短連接指建立SOCKET連接后發(fā)送后接收完數(shù)據(jù)后馬上斷開連接,一般銀行都使用短連接

  2. 長連接就是指在基于tcp的通訊中,一直保持連接,不管當(dāng)前是否發(fā)送或者接收數(shù)據(jù)。而短連接就是只有在有數(shù)據(jù)傳輸?shù)臅r(shí)候才進(jìn)行連接,客戶-服務(wù)器通信/傳輸數(shù)據(jù)完畢就關(guān)閉連接。

  3. 通信方式
    各網(wǎng)元之間共有兩種連接方式:長連接和短連接。所謂長連接,指在一個(gè)TCP連接上可以連續(xù)發(fā)送多個(gè)數(shù)據(jù)包,在TCP連接保持期間,如果沒有數(shù)據(jù)包發(fā)送,需 要雙方發(fā)檢測包以維持此連接。短連接是指通信雙方有數(shù)據(jù)交互時(shí),就建立一個(gè)TCP連接,數(shù)據(jù)發(fā)送完成后,則斷開此TCP連接,即每次TCP連接只完成一對(duì) CMPP消息的發(fā)送。
    現(xiàn)階段,要求ISMG之間必須采用長連接的通信方式,建議SP與ISMG之間采用長連接的通信方式。

  4. 短連接:比如http的,只是連接、請(qǐng)求、關(guān)閉,過程時(shí)間較短,服務(wù)器若是一段時(shí)間內(nèi)沒有收到請(qǐng)求即可關(guān)閉連接。長連接:有些服務(wù)需要長時(shí)間連接到服務(wù)器,比如CMPP,一般需要自己做在線維持。

實(shí)現(xiàn)socket長連接

每次我們?cè)L問PHP腳本的時(shí)候,都是當(dāng)所有的PHP腳本執(zhí)行完成后,我們才得到返回結(jié)果。如果我們需要一個(gè)腳本持續(xù)的運(yùn)行,那么我們就要通過php長連接的方式,來達(dá)到運(yùn)行目的。

想要玩長連接就需要跟socket打交道,socket的封裝自然是少不的了。下面就通過代碼來進(jìn)行socket長連接。

其實(shí)例代碼如下:

<?php$sfd = socket_create(AF_INET, SOCK_STREAM, 0);  socket_bind($sfd, "0.0.0.0", 1234);  socket_listen($sfd, 511);  socket_set_option($sfd, SOL_SOCKET, SO_REUSEADDR, 1);  socket_set_nonblock($sfd);  $rfds = array($sfd);  $wfds = array();  do{      $rs = $rfds;      $ws = $wfds;      $es = array();      $ret = socket_select($rs, $ws, $es, 3);            //讀取事件     foreach($rs as $fd){          if($fd == $sfd){            $cfd = socket_accept($sfd);             socket_set_nonblock($cfd);              $rfds[] = $cfd;              echo "new client coming, fd=$cfd/n";          }else{              $msg = socket_read($fd, 1024);              if($msg <= 0){                  //close              }else{                                 echo "on message, fd=$fd data=$msg/n";              }          }      }       //寫入事件     foreach($ws as $fd){          socket_write($fd, ........);      }       }while(true);?>

下面來提高下效率:

<?php$sfd = stream_socket_server ('tcp://0.0.0.0:1234', $errno, $errstr);  stream_set_blocking($sfd, 0);  $base = event_base_new();  $event = event_new();  event_set($event, $sfd, EV_READ | EV_PERSIST, 'ev_accept', $base);  event_base_set($event, $base);  event_add($event);  event_base_loop($base);  function ev_accept($socket, $flag, $base)  {      $connection = stream_socket_accept($socket);      stream_set_blocking($connection, 0);      $buffer = event_buffer_new($connection, 'ev_read', NULL, 'ev_error',  $connection);          event_buffer_base_set($buffer, $base);      event_buffer_timeout_set($buffer, 30, 30);      event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);      event_buffer_priority_set($buffer, 10);      event_buffer_enable($buffer, EV_READ | EV_PERSIST);  }  function ev_error($buffer, $error, $connection)  {      event_buffer_disable($buffer, EV_READ | EV_WRITE);                      event_buffer_free($buffer);                      fclose($connection);                  }  function ev_read($buffer, $connection)  {      $read = event_buffer_read($buffer, 256);      //do something....  }?>

隨著人數(shù)的增長,并發(fā)的提升,單個(gè)進(jìn)程已經(jīng)滿足不了需求了,現(xiàn)成的就有擴(kuò)展和庫來解決這個(gè)事,比如:swoole,workerman等?但是,我們?cè)谑褂胮hp來開發(fā)web的時(shí)候,也沒有使用webserver相關(guān)的庫來做開發(fā)對(duì)不對(duì)?咱只是簡單的echo而已。這些繁雜的事都交給了nginx或者是apache,是他們義無反顧的頂在前面,讓我們可以專心寫邏輯。寫socket服務(wù)不比寫web高級(jí),都是打碼,都是完成需求,通信那層都是固定的,只不過一個(gè)由nginx完成,另一個(gè)由自己完成。。可是現(xiàn)在不需要自己完成了,類似nginx+fpm的方案,fooking+fpm=php長連接,gateway用于承載連接,router用于轉(zhuǎn)發(fā)消息。

其代碼如下所示:

<?php$sid = $_SERVER['SESSIONID'];//這是sessionid  $data = file_get_contents("php://input");//這樣就能拿到請(qǐng)求內(nèi)容了  //想要返回消息只需要兩步  header('Content-Length: 11');//返回給客戶端字節(jié)數(shù)  echo "hello world";  //想要給別的用戶發(fā)消息  include 'api.php';  $router = new RouterClient('router host', 'router port');  $router->sendMsg(用戶sessionid, "fuck you");  //想要給所有人要消息  $router->sendAllMsg("fuck all");  //想給指定組發(fā)消息(類似redis的pub/sub)  $router->publish("channel name", "fuck all");?>

【相關(guān)教程推薦】

1. 《VeVb.com獨(dú)孤九賤(4)-php視頻教程》

2. php編程從入門到精通全套教程

以上就是php socket如何實(shí)現(xiàn)長連接的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注 其它相關(guān)文章!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 于都县| 泽普县| 永丰县| 凉城县| 东安县| 宁武县| 屏东市| 盖州市| 壤塘县| 天津市| 招远市| 青神县| 德令哈市| 台东县| 镇巴县| 新干县| 武功县| 项城市| 皋兰县| 马边| 鸡西市| 陈巴尔虎旗| 新野县| 九龙坡区| 山东| 广西| 孝义市| 吉木乃县| 新晃| 綦江县| 普陀区| 兴化市| 永宁县| 汶上县| 土默特左旗| 红桥区| 五峰| 卓尼县| 利津县| 聂拉木县| 会宁县|