這篇文章將為大家詳細講解有關(guān)workerman實時推送的示例,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
崇仁ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!實現(xiàn)基于workerman的實時推送,摒棄ajax輪詢的方法
先扯些這些內(nèi)容:
TCP/IP
TCP/IP是個協(xié)議組,可分為三個層次:網(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ù)器每進行一次HTTP操作,就建立一次連接,但任務(wù)結(jié)束就中斷連接。
也可以這樣說:短連接是指SOCKET連接后發(fā)送后接收完數(shù)據(jù)后馬上斷開連接。
長連接
連接->傳輸數(shù)據(jù)->保持連接 -> 傳輸數(shù)據(jù)-> 。。。 ->關(guān)閉連接。
長連接指建立SOCKET連接后不管是否使用都保持連接,但安全性較差。
http的長連接
HTTP也可以建立長連接的,使用Connection:keep-alive,HTTP 1.1默認進行持久連接。HTTP1.1和HTTP1.0相比較而言,較大的區(qū)別就是增加了持久連接支持(貌似新的 http1.0 可以顯示的指定 keep-alive),但還是無狀態(tài)的,或者說是不可以信任的。
什么時候用長連接,短連接?
長連接多用于操作頻繁,點對點的通訊,而且連接數(shù)不能太多情況,。每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那么處理速度會降低很多,所以每個操作完后都不斷開,次處理時直接發(fā)送數(shù)據(jù)包就OK了,不用建立TCP連接。例如:數(shù)據(jù)庫的連接用長連接, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創(chuàng)建也是對資源的浪費。
而像WEB網(wǎng)站的http服務(wù)一般都用短鏈接,因為長連接對于服務(wù)端來說會耗費一定的資源,而像WEB網(wǎng)站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源,如果用長連接,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話,那可想而知吧。所以并發(fā)量大,但每個用戶無需頻繁操作情況下需用短連好。
workerman是啥子?Workerman是一款純PHP開發(fā)的開源高性能的PHP socket 服務(wù)器框架。被廣泛的用于手機app、移動通訊,微信小程序,手游服務(wù)端、網(wǎng)絡(luò)游戲、PHP聊天室、硬件通訊、智能家居、車聯(lián)網(wǎng)、物聯(lián)網(wǎng)等領(lǐng)域的開發(fā)。 支持TCP長連接,支持Websocket、HTTP等協(xié)議,支持自定義協(xié)議。擁有異步Mysql、異步Redis、異步Http、異步消息隊列等眾多高性能組件。
開始步入正題:為了達到實時通訊,很多時候我們采用了ajax輪詢機制,如圖:
后面可以采用workerman方式來實現(xiàn),項目也是tp寫的,官方手冊這么說到
與其它mvc框架結(jié)合建議以上圖的方式(ThinkPHP為例):
1、ThinkPHP與Workerman是兩個獨立的系統(tǒng),獨立部署(可部署在不同服務(wù)器),互不干擾。
2、ThinkPHP以HTTP協(xié)議提供網(wǎng)頁頁面在瀏覽器渲染展示。
3、ThinkPHP提供的頁面的js發(fā)起websocket連接,連接workerman
4、連接后給Workerman發(fā)送一個數(shù)據(jù)包(包含用戶名密碼或者某種token串)用于驗證websocket連接屬于哪個用戶。
5、僅在ThinkPHP需要向瀏覽器推送數(shù)據(jù)時,才調(diào)用workerman的socket接口推送數(shù)據(jù)。
6、其余請求還是按照原本ThinkPHP的HTTP方式調(diào)用處理。
總結(jié):
把Workerman作為一個可以向瀏覽器推送的通道,僅僅在需要向瀏覽器推送數(shù)據(jù)時才調(diào)用Workerman接口完成推送。業(yè)務(wù)邏輯全部在ThinkPHP中完成。
ok,到這里,把workerman容器跑起來,注意這里是CLI模式運行
然后再我們項目接收信息中這么玩,附上代碼
接著,我們在用戶向用戶發(fā)送信息的時候添加
// 指明給誰推送,為空表示向所有在線用戶推送 $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里面的推送核心代碼實現(xiàn)
// 全局數(shù)組保存uid在線數(shù)據(jù) $uidConnectionMap = array(); // 記錄最后一次廣播的在線用戶數(shù) $last_online_count = 0; // PHPSocketIO服務(wù) $sender_io = new SocketIO(2120); // 客戶端發(fā)起連接事件時,設(shè)置連接socket的各種事件回調(diào) // 當$sender_io啟動后監(jiān)聽一個http端口,通過這個端口可以給任意uid或者所有uid推送數(shù)據(jù) $sender_io->on('workerStart', function(){ // 監(jiān)聽一個http端口 $inner_http_worker = new Worker('http://0.0.0.0:2121'); // 當http客戶端發(fā)來數(shù)據(jù)時觸發(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,大功告成!
關(guān)于“workerman實時推送的示例”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。