您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Swoole webSocket消息服務系統代碼怎么寫”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Swoole webSocket消息服務系統代碼怎么寫”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
Swoole屬于php中的一個超級擴展,它會接管PHP的進程,管理和分配worker,但他依賴 PHP-Cli模式。Swoole和Yaf有相似的地方,它們都是以守護進程的模式、常駐內存的方式達到提高處理性能。
Swoole內置了TCP、UDP、WebSocket、協程、異步、Redis/Mysql鏈接池等高效開發手段和方法,當然對于新模式也有新的挑戰,比如swoole不能使用die,會致使worker滑落,協程使用后要注意使用回調的過程,如果對php的基礎知識不了解的同學,可以翻看我之前的php博客里的總結,這里就不過多敘述了。
EasySwoole是一款非常簡單上手易操作的Swoole框架,上線2年多以來經得住生產環境的考驗,官網文檔寫的也很詳細,還有專門解答的QQ群,大佬們會解答很多問題。
之前我使用composer進行安裝的(composer是php中管理依賴包的工具,和node里面的npm,python的pip 一樣),現在都使用docker鏡像直接操作了。
docker pull easyswoole/easyswoole3 docker run -ti -p 9501:9501 -p 80:80 --name easyswoole easyswoole/easyswoole3
項目初始目錄結構:
├── EasySwooleEvent.php ├── bootstrap.php ├── composer.json ├── composer.lock ├── dev.php ├── easyswoole ├── produce.php └── vendor
1.在EasySwooleEvent.php文件中加載初始化需要的Mysql、redis配置文件,所有需要的服務都需要在啟動文件中進行注冊,才能使用。
public static function loadConf() { $ConfPath = EASYSWOOLE_ROOT . '/App/Conf/'; $Conf = Config::getInstance(); $files = File::scanDirectory($ConfPath); if (!is_array($files['files'])) { return; } foreach ($files['files'] as $file) { $data = require_once $file; $Conf->setConf(strtolower(basename($file, '.php')), (array)$data); } }
2.注冊Mysql連接池,Mysql連接池主要設置參數,
<?php use EasySwoole\ORM\Db\Config as DBConfig; use EasySwoole\ORM\Db\Connection; use EasySwoole\ORM\DbManager; return [ //mysql數據庫配置 'mysql-msg' => [ 'host' => '59.110.162.133', 'port' => '3306', 'database' => 'swoole_msg', //cpwxw2_db_v2 'username' => 'work', 'password' => 'cp2018csq123456', 'timeout' => 300, 'charset' => 'utf8mb4' ], //Mysql連接池配置 'conn_pool' => [ 'timeOut' => '3.0', //設置獲取連接池對象超時時間 'checkOut' => 30 * 1000, //設置檢測連接存活執行回收和創建的周期 'maxidleTime' => 15, //連接池對象最大閑置時間(秒) 'maxObjectNumber' => 100, //設置最大連接池存在連接對象數量 'minObjectNumber' => 5, //設置最小連接池存在連接對象數量 'autoPing' => 5, //設置自動ping客戶端鏈接的間隔 ], ];
3.注冊redis鏈接池
use \EasySwoole\Redis\Config\RedisConfig; use \EasySwoole\RedisPool\RedisPool; $redisConf = GlobalConfig::getInstance()->getConf('redis'); RedisPool::getInstance()->register(new RedisConfig($redisConf),'redis');
4.注冊自定義log
use \EasySwoole\EasySwoole\Logger; Logger::getInstance(new \App\Log\LogHandel());
5.我的項目里還使用了crontab模塊
use Swoole\Coroutine\Scheduler; use EasySwoole\EasySwoole\Crontab\Crontab; //用戶通知隊列 Crontab::getInstance()->addTask(\App\Crontab\PushUserNoticeMsg::class);
6.添加熱啟動
Swoole的服務屬于常駐內存加載類型的服務,所以每次修改代碼后都需要重啟服務,所以為了方便,添加了熱加載目錄,熱加載原理就是當檢測到指定目錄有代碼更新時,用傳遞信號的方式進行,指揮進程進行重新加載。
$hotReloadOptions = new \EasySwoole\HotReload\HotReloadOptions; $hotReload = new \EasySwoole\HotReload\HotReload($hotReloadOptions); $hotReloadOptions->setMonitorFolder([EASYSWOOLE_ROOT . '/App']); $server = ServerManager::getInstance()->getSwooleServer(); $hotReload->attachToServer($server);
7.啟動/停止服務,參數說明
-mode 說明啟動服務類型 -d 以守護進程的方式
php easyswoole server start -mode=websocket -d php easyswoole server stop
1.高性能的異步操作
如果是不依賴于結果的計算,異步操作提高性能的有效手段之一,異步操作不需要等待結果,更好的利用CPU和I/O傳輸。
use EasySwoole\EasySwoole\Task\TaskManager; TaskManager::getInstance()->async(function () use ($tableName,$data) { // todo code ... });
Redis/Mysql使用
在高并發情況下,資源浪費的占用時間越短越好,可以提高程序的服務效率。在ORM默認情況下是使用defer方法獲取pool內的連接資源,并在協程退出時自動歸還,在此情況下,在帶來便利的同時,會造成不必要資源的浪費。
我們可以使用invoke方式,讓ORM查詢結束后馬上歸還資源,可以提高資源的利用率。
Mysql的使用Demo.
DbManager::getInstance()->invoke(function (ClientInterface $client) use ($where, $tableName, $count) { $pushMsgModel = PushMsgModel::invoke($client); $pushMsgObj = $pushMsgModel->tableName($tableName) ->field(['push_id']) ->get($where); }, self::MYSQL_CONN_NAME);
Redis的使用Demo.
## invoke方式 public function setAuthorFd(int $uid, int $fd) { RedisPool::invoke(function (Redis $redis) use ($fd, $uid) { $sRet = $redis->zAdd(self::PUSH_MSG_AUTHOR_NOTICE_SYSTEM, $uid, $fd); }, self::REDIS_CONN_NAME); } ## defer方式 $redis = \EasySwoole\RedisPool\RedisPool::defer('redis'); $data = $redis->lRange(self::PUSH_MSG_COMMENT_DELAY_LISTS, 0, 1000);
1.WebSocket協議是什么
WebSocket協議是基于TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端。
在沒有WebSocket協議之前,在網頁中,實現一個聊天室只能使用ajax 不斷輪詢,請求服務器是否有數據產生,而這樣的實現方法會出現一系列的問題:
如果輪詢時間間隔太短,會導致客戶端和服務端在一個時間段內不斷的進行http tcp的握手/揮手動作和http 請求頭,響應頭的傳輸,大量消耗服務器資源,如果用戶量大的情況,會造成服務器的繁忙以至于宕機
客戶端每次只能通過發送http 請求獲得服務器是否有數據返回,且數據的及時性無法保證
正因為在這種情況下,所以WebSocket出現了,它只需要一次http握手,就可以保持一個長連接,使得服務器可以主動發送消息給客戶端,大大減少了輪詢機制的消耗。
2.WebSocket協議實現原理
在實現websocket連線過程中,需要通過瀏覽器發出websocket連線請求,然后服務器發出回應,這個過程通常稱為握手 。
在 WebSocket API,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。在此WebSocket 協議中,為我們實現即時服務帶來了兩大好處:
Header: 互相溝通的Header是很小的-大概只有 2 Bytes
Server Push: 服務器的推送,服務器不再被動的接收到瀏覽器的請求之后才返回數據,而是在有新數據時就主動推送給瀏覽器。
//$fd,指的是系統里的文件描述符fd use EasySwoole\EasySwoole\ServerManager; $server = ServerManager::getInstance()->getSwooleServer(); $server->push($fd,json_encode($messageData)); //獲取當前鏈接的詳細信息 $info = $server->getClientInfo($fd); //獲取全部websocket中的鏈接fd //全員在線消息通知 $server = ServerManager::getInstance()->getSwooleServer(); $start_fd = 0; while(true) { $conn_list = $server->getClientList( $start_fd, $this->limit ); if ($conn_list===false || count($conn_list) === 0 || empty($conn_list)) { break; } $start_fd = end($conn_list); foreach ($conn_list as $fd){ $info = $server->getClientInfo($fd); if ($info && $info['websocket_status'] === WEBSOCKET_STATUS_FRAME) { $server->push($fd, json_encode($this->pushMsg)); } } }
讀到這里,這篇“Swoole webSocket消息服務系統代碼怎么寫”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。