亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

    基于workerman的實(shí)時(shí)推送(摒棄ajax輪詢)

    下面由workerman教程欄目給大家介紹實(shí)現(xiàn)基于workerman的實(shí)時(shí)推送,摒棄ajax輪詢的方法,希望對(duì)需要的朋友有所幫助!

    基于workerman的實(shí)時(shí)推送(摒棄ajax輪詢)

    先扯些這些內(nèi)容:

    TCP/IP

    TCP/IP是個(gè)協(xié)議組,可分為三個(gè)層次:網(wǎng)絡(luò)層、傳輸層和應(yīng)用層。

    在網(wǎng)絡(luò)層有IP協(xié)議、ICMP協(xié)議、ARP協(xié)議、RARP協(xié)議和BOOTP協(xié)議。

    在傳輸層中有TCP協(xié)議與UDP協(xié)議。

    在應(yīng)用層有:

    TCP包括FTP、HTTP、TELNET、SMTP等協(xié)議

    UDP包括DNS、TFTP等協(xié)議

    短連接

    連接->傳輸數(shù)據(jù)->關(guān)閉連接

    HTTP是無狀態(tài)的,瀏覽器和服務(wù)器每進(jìn)行一次HTTP操作,就建立一次連接,但任務(wù)結(jié)束就中斷連接。

    也可以這樣說:短連接是指SOCKET連接后發(fā)送后接收完數(shù)據(jù)后馬上斷開連接。

    長連接

    連接->傳輸數(shù)據(jù)->保持連接 -> 傳輸數(shù)據(jù)-> 。。。 ->關(guān)閉連接。

    長連接指建立SOCKET連接后不管是否使用都保持連接,但安全性較差。

    http的長連接

    HTTP也可以建立長連接的,使用Connection:keep-alive,HTTP 1.1默認(rèn)進(jìn)行持久連接。HTTP1.1和HTTP1.0相比較而言,最大的區(qū)別就是增加了持久連接支持(貌似最新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態(tài)的,或者說是不可以信任的。

    什么時(shí)候用長連接,短連接?

    長連接多用于操作頻繁,點(diǎn)對(duì)點(diǎn)的通訊,而且連接數(shù)不能太多情況,。每個(gè)TCP連接都需要三步握手,這需要時(shí)間,如果每個(gè)操作都是先連接,再操作的話那么處理速度會(huì)降低很多,所以每個(gè)操作完后都不斷開,次處理時(shí)直接發(fā)送數(shù)據(jù)包就OK了,不用建立TCP連接。例如:數(shù)據(jù)庫的連接用長連接, 如果用短連接頻繁的通信會(huì)造成socket錯(cuò)誤,而且頻繁的socket 創(chuàng)建也是對(duì)資源的浪費(fèi)。

    而像WEB網(wǎng)站的http服務(wù)一般都用短鏈接,因?yàn)殚L連接對(duì)于服務(wù)端來說會(huì)耗費(fèi)一定的資源,而像WEB網(wǎng)站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會(huì)更省一些資源,如果用長連接,而且同時(shí)有成千上萬的用戶,如果每個(gè)用戶都占用一個(gè)連接的話,那可想而知吧。所以并發(fā)量大,但每個(gè)用戶無需頻繁操作情況下需用短連好。

    workerman是啥子?Workerman是一款純PHP開發(fā)的開源高性能的PHP socket 服務(wù)器框架。被廣泛的用于手機(jī)app、移動(dòng)通訊,微信小程序,手游服務(wù)端、網(wǎng)絡(luò)游戲、PHP聊天室、硬件通訊、智能家居、車聯(lián)網(wǎng)、物聯(lián)網(wǎng)等領(lǐng)域的開發(fā)。 支持TCP長連接,支持Websocket、HTTP等協(xié)議,支持自定義協(xié)議。擁有異步Mysql、異步Redis、異步Http、異步消息隊(duì)列等眾多高性能組件。

    開始步入正題:為了達(dá)到實(shí)時(shí)通訊,很多時(shí)候我們采用了ajax輪詢機(jī)制,如圖:

    基于workerman的實(shí)時(shí)推送(摒棄ajax輪詢)

    后面可以采用workerman方式來實(shí)現(xiàn),項(xiàng)目也是tp寫的,官方手冊(cè)這么說到

    與其它mvc框架結(jié)合建議以上圖的方式(ThinkPHP為例):

    1、ThinkPHP與Workerman是兩個(gè)獨(dú)立的系統(tǒng),獨(dú)立部署(可部署在不同服務(wù)器),互不干擾。

    2、ThinkPHP以HTTP協(xié)議提供網(wǎng)頁頁面在瀏覽器渲染展示。

    3、ThinkPHP提供的頁面的js發(fā)起websocket連接,連接workerman

    4、連接后給Workerman發(fā)送一個(gè)數(shù)據(jù)包(包含用戶名密碼或者某種token串)用于驗(yàn)證websocket連接屬于哪個(gè)用戶。

    5、僅在ThinkPHP需要向?yàn)g覽器推送數(shù)據(jù)時(shí),才調(diào)用workerman的socket接口推送數(shù)據(jù)。

    6、其余請(qǐng)求還是按照原本ThinkPHP的HTTP方式調(diào)用處理。

    總結(jié):

    把Workerman作為一個(gè)可以向?yàn)g覽器推送的通道,僅僅在需要向?yàn)g覽器推送數(shù)據(jù)時(shí)才調(diào)用Workerman接口完成推送。業(yè)務(wù)邏輯全部在ThinkPHP中完成。

    ok,到這里,把workerman容器跑起來,注意這里是CLI模式運(yùn)行

    基于workerman的實(shí)時(shí)推送(摒棄ajax輪詢)

    然后再我們項(xiàng)目接收信息中這么玩,附上代碼

    <script>     // 連接服務(wù)端     var socket = io('http://127.0.0.1:2120');     // uid可以是自己網(wǎng)站的用戶id,以便針對(duì)uid推送     uid = 123;     // socket連接后以u(píng)id登錄     socket.on('connect', function(){     socket.emit('login', uid);     });     // 后端推送來消息時(shí)     socket.on('new_msg', function(msg){         console.log("收到消息:"+msg);  //自己業(yè)務(wù)邏輯處理     });      </script>

    接著,我們?cè)谟脩粝蛴脩舭l(fā)送信息的時(shí)候添加

    // 指明給誰推送,為空表示向所有在線用戶推送         $to_uid = "123";         // 推送的url地址         $push_api_url = "http://127.0.0.1:2121/";         $post_data = array(            "type" => "publish",            "content" => "數(shù)據(jù)",            "to" => $to_uid,          );         $ch = curl_init ();         curl_setopt ( $ch, CURLOPT_URL, $push_api_url );         curl_setopt ( $ch, CURLOPT_POST, 1 );         curl_setopt ( $ch, CURLOPT_HEADER, 0 );         curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );         curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data );         curl_setopt ($ch, CURLOPT_HTTPHEADER, array("Expect:"));         $return = curl_exec ( $ch );         curl_close ( $ch );         var_export($return);

    其中,workerman里面的推送核心代碼實(shí)現(xiàn)

    // 全局?jǐn)?shù)組保存uid在線數(shù)據(jù) $uidConnectionMap = array(); // 記錄最后一次廣播的在線用戶數(shù) $last_online_count = 0;     // PHPSocketIO服務(wù) $sender_io = new SocketIO(2120); // 客戶端發(fā)起連接事件時(shí),設(shè)置連接socket的各種事件回調(diào)   // 當(dāng)$sender_io啟動(dòng)后監(jiān)聽一個(gè)http端口,通過這個(gè)端口可以給任意uid或者所有uid推送數(shù)據(jù) $sender_io->on('workerStart', function(){     // 監(jiān)聽一個(gè)http端口     $inner_http_worker = new Worker('http://0.0.0.0:2121');     // 當(dāng)http客戶端發(fā)來數(shù)據(jù)時(shí)觸發(fā)     $inner_http_worker->onMessage = function($http_connection, $data){         global $uidConnectionMap;         $_POST = $_POST ? $_POST : $_GET;         // 推送數(shù)據(jù)的url格式 type=publish&to=uid&content=xxxx         switch(@$_POST['type']){             case 'publish':                 global $sender_io;                 $to = @$_POST['to'];                 $_POST['content'] = htmlspecialchars(@$_POST['content']);                 // 有指定uid則向uid所在socket組發(fā)送數(shù)據(jù)                 if($to){                     $sender_io->to($to)->emit('new_msg', $_POST['content']);                 // 否則向所有uid推送數(shù)據(jù)                 }else{                     $sender_io->emit('new_msg', @$_POST['content']);                 }                 // http接口返回,如果用戶離線socket返回fail                 if($to && !isset($uidConnectionMap[$to])){                     return $http_connection->send('offline');                 }else{                     return $http_connection->send('ok');                 }         }         return $http_connection->send('fail');     };      });   if(!defined('GLOBAL_START')) {     Worker::runAll(); }

    ok,大功告成!

    贊(0)
    分享到: 更多 (0)
    網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)