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

来源:https://www.cnblogs.com/a609251438/archive/2020/05/11/12871299.html
-Advertisement-
Play Games

先扯些這些內容: TCP/IP TCP/IP是個協議組,可分為三個層次:網路層、傳輸層和應用層。 在網路層有IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議。 在傳輸層中有TCP協議與UDP協議。 在應用層有: TCP包括FTP、HTTP、TELNET、SMTP等協議 UDP包括DN ...


先扯些這些內容:

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是一款純PHP開發的開源高性能的PHP socket 伺服器框架。被廣泛的用於手機app、移動通訊,微信小程式,手游服務端、網路游戲、PHP聊天室、硬體通訊、智能家居、車聯網、物聯網等領域的開發。 支持TCP長連接,支持Websocket、HTTP等協議,支持自定義協議。擁有非同步Mysql、非同步Redis、非同步Http、非同步消息隊列等眾多高性能組件。

開始步入正題:為了達到實時通訊,很多時候我們採用了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模式運行

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

<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,大功告成!

更多學習內容請訪問:

騰訊T3-T4標準精品PHP架構師教程目錄大全,只要你看完保證薪資上升一個臺階(持續更新)圖標

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、Swagger 1、什麼是 Swagger ? Swagger 是一個規範和完整的框架,用於生成、描述、調用以及可視化的 Restful 風格的 Web 服務。 簡單的理解:是一款 REST API 文檔生成工具,生成線上的介面文檔,方便介面測試。 2、為什麼使用 Swagger? 前後端分離開 ...
  • 迴圈結構有三個:while型迴圈、for型迴圈、do-while型迴圈 while型迴圈和for型迴圈都屬於當型迴圈,do-while型迴圈屬於直到型迴圈(少見)。 1.while型迴圈for型迴圈 結構: while(【布爾表達式】){ 【迴圈語句】; } 先運行【布爾表達式】,如果其值為真,執行 ...
  • 前言 本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 時間序列 1、時間序列圖 時間序列圖用於可視化給定指標如何隨時間變化。在這裡,您可以瞭解1949年至1969年之間的航空客運流量如何變化。 # Import Data df ...
  • Spring 框架的核心特性是可以用於開發任何 Java 應用程式,但是在 Java EE 平臺上構建 web 應用程式是需要擴展的。 Spring 框架的目標是使 J2EE 開發變得更容易使用。 ...
  • 單例模式,是Java中比較常見的一個設計模式,也是我在面試時經常會問到的一個問題。 經過我的初步統計,基本上有60%左右的人可以說出2-4種單例的實現方式,有40%左右的人可以說出5-6種單例的實現方式,只有20%左右的人能夠說出7種單例的實現。 而只有不到1%的人能夠說出7種以上的單例實現。 其實 ...
  • 你是否有過這麼一段經歷,一直做著OA,CRM管理系統等傳統項目,簡歷技能開頭第一行,基本都是“Java基礎扎實”,然後下麵接著就是熟悉XXX。然後不斷列名詞,舉例一下: Java基礎扎實 熟悉Mysql… 熟悉Redis… 熟悉HTML/CSS/JS… 這個,是否就是你的簡歷套路??? 但是你發現, ...
  • 面試的時候,很多人都小心翼翼,如履薄冰,生怕自己說錯一句話,就錯失機會,擔心,面試緊張、卡殼、答不上來怎麼辦? 被面試官弔打,碾壓,是常態,畢竟大多數面試官工作經驗和技術都更加豐富嘛。 但是,術業有專攻,總有一些技術牛逼的程式員可以弔打、碾壓面試官! 本人經常隔段時間就偷偷投點簡歷,請假出去面試幾次 ...
  • 一個小伙伴最近參加某一線互聯網公司的面試,被問到了一些併發相關的問題,看看大家能否答出來: (1)synchronized的CPU原語級別是如何實現的? (2)無鎖、偏向鎖、輕量級鎖、重量級鎖有什麼差別,升級過程如何? (3)線程間通信,同機器進程間通信,跨機器進程間通信,各有什麼方法? (4)下列 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...