站長資訊網
        最全最豐富的資訊網站

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

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

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

        先扯些這些內容:

        TCP/IP

        TCP/IP是個協議組,可分為三個層次:網絡層、傳輸層和應用層。

        在網絡層有IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議。

        在傳輸層中有TCP協議與UDP協議。

        在應用層有:

        TCP包括FTP、HTTP、TELNET、SMTP等協議

        UDP包括DNS、TFTP等協議

        短連接

        連接->傳輸數據->關閉連接

        HTTP是無狀態的,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,但任務結束就中斷連接。

        也可以這樣說:短連接是指SOCKET連接后發送后接收完數據后馬上斷開連接。

        長連接

        連接->傳輸數據->保持連接 -> 傳輸數據-> 。。。 ->關閉連接。

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

        http的長連接

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

        什么時候用長連接,短連接?

        長連接多用于操作頻繁,點對點的通訊,而且連接數不能太多情況,。每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那么處理速度會降低很多,所以每個操作完后都不斷開,次處理時直接發送數據包就OK了,不用建立TCP連接。例如:數據庫的連接用長連接, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創建也是對資源的浪費。

        而像WEB網站的http服務一般都用短鏈接,因為長連接對于服務端來說會耗費一定的資源,而像WEB網站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源,如果用長連接,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話,那可想而知吧。所以并發量大,但每個用戶無需頻繁操作情況下需用短連好。

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

        開始步入正題:為了達到實時通訊,很多時候我們采用了ajax輪詢機制,如圖:

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

        后面可以采用workerman方式來實現,項目也是tp寫的,官方手冊這么說到

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

        1、ThinkPHP與Workerman是兩個獨立的系統,獨立部署(可部署在不同服務器),互不干擾。

        2、ThinkPHP以HTTP協議提供網頁頁面在瀏覽器渲染展示。

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

        4、連接后給Workerman發送一個數據包(包含用戶名密碼或者某種token串)用于驗證websocket連接屬于哪個用戶。

        5、僅在ThinkPHP需要向瀏覽器推送數據時,才調用workerman的socket接口推送數據。

        6、其余請求還是按照原本ThinkPHP的HTTP方式調用處理。

        總結:

        把Workerman作為一個可以向瀏覽器推送的通道,僅僅在需要向瀏覽器推送數據時才調用Workerman接口完成推送。業務邏輯全部在ThinkPHP中完成。

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

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

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

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

        接著,我們在用戶向用戶發送信息的時候添加

        // 指明給誰推送,為空表示向所有在線用戶推送         $to_uid = "123";         // 推送的url地址         $push_api_url = "http://127.0.0.1:2121/";         $post_data = array(            "type" => "publish",            "content" => "數據",            "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里面的推送核心代碼實現

        // 全局數組保存uid在線數據 $uidConnectionMap = array(); // 記錄最后一次廣播的在線用戶數 $last_online_count = 0;     // PHPSocketIO服務 $sender_io = new SocketIO(2120); // 客戶端發起連接事件時,設置連接socket的各種事件回調   // 當$sender_io啟動后監聽一個http端口,通過這個端口可以給任意uid或者所有uid推送數據 $sender_io->on('workerStart', function(){     // 監聽一個http端口     $inner_http_worker = new Worker('http://0.0.0.0:2121');     // 當http客戶端發來數據時觸發     $inner_http_worker->onMessage = function($http_connection, $data){         global $uidConnectionMap;         $_POST = $_POST ? $_POST : $_GET;         // 推送數據的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組發送數據                 if($to){                     $sender_io->to($to)->emit('new_msg', $_POST['content']);                 // 否則向所有uid推送數據                 }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)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 久久精品无码一区二区日韩AV | 久久精品夜夜夜夜夜久久| 99国内精品久久久久久久| 日韩人妻无码精品一专区| 精品人体无码一区二区三区| 国产福利在线观看精品| 无码久久精品国产亚洲Av影片 | 久久夜色精品国产噜噜亚洲AV| 精品久久久久久国产免费了| 亚洲国产精品免费视频| 国产欧美国产精品第一区| 国产精品亲子乱子伦xxxx裸| 亚洲色精品vr一区二区三区| 久久精品无码免费不卡| 国产亚洲精品看片在线观看| 3级黄性日本午夜精品| 精品久久一区二区三区| 国产AV国片精品有毛| 精品久久久久久久久午夜福利| 亚洲精品美女久久777777| 四虎国产精品永久在线看| 久久久精品国产亚洲成人满18免费网站 | 久久99精品久久久久久水蜜桃| 国产高清在线精品一区二区| 四虎国产精品永久地址51| 欧美久久精品一级c片片| 久久99热狠狠色精品一区| 国产精品一久久香蕉国产线看| 东京热TOKYO综合久久精品| 精品日韩亚洲AV无码一区二区三区| 日韩精品国产另类专区| 日韩精品少妇无码受不了| 中文字幕精品无码一区二区三区 | 九九精品在线视频| 久久精品无码一区二区三区日韩| 国产精品 猎奇 另类视频| 精品久久久久久无码免费| 久久久久久亚洲精品无码| 亚洲国产高清精品线久久 | 国产叼嘿久久精品久久| 国产成人久久精品二区三区|