欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swoole?webSocket消息服務(wù)系統(tǒng)代碼設(shè)計詳解

 更新時間:2023年03月23日 15:26:48   作者:stark張宇  
這篇文章主要為大家介紹了Swoole?webSocket消息服務(wù)系統(tǒng)代碼設(shè)計詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

概述

已經(jīng)Swoole系列的第二篇知識點了,前一篇主要的針對處理的是方案設(shè)計,這一篇主要是代碼實現(xiàn)的內(nèi)容,主要介紹高性能的原因已經(jīng)實現(xiàn),編程框架使用EasySwoole。

Swoole 與 EasySwoole

Swoole屬于php中的一個超級擴展,它會接管PHP的進程,管理和分配worker,但他依賴 PHP-Cli模式。Swoole和Yaf有相似的地方,它們都是以守護進程的模式、常駐內(nèi)存的方式達到提高處理性能。

Swoole內(nèi)置了TCP、UDP、WebSocket、協(xié)程、異步、Redis/Mysql鏈接池等高效開發(fā)手段和方法,當(dāng)然對于新模式也有新的挑戰(zhàn),比如swoole不能使用die,會致使worker滑落,協(xié)程使用后要注意使用回調(diào)的過程,如果對php的基礎(chǔ)知識不了解的同學(xué),可以翻看我之前的php博客里的總結(jié),這里就不過多敘述了。

EasySwoole是一款非常簡單上手易操作的Swoole框架,上線2年多以來經(jīng)得住生產(chǎn)環(huán)境的考驗,官網(wǎng)文檔寫的也很詳細,還有專門解答的QQ群,大佬們會解答很多問題。

安裝EasySwoole框架

之前我使用composer進行安裝的(composer是php中管理依賴包的工具,和node里面的npm,python的pip 一樣),現(xiàn)在都使用docker鏡像直接操作了。

docker pull easyswoole/easyswoole3
docker run -ti -p 9501:9501 -p 80:80 
--name easyswoole easyswoole/easyswoole3 

項目初始目錄結(jié)構(gòu):

├── EasySwooleEvent.php
├── bootstrap.php
├── composer.json
├── composer.lock
├── dev.php
├── easyswoole
├── produce.php
└── vendor

注冊服務(wù) 與啟動加載

1.在EasySwooleEvent.php文件中加載初始化需要的Mysql、redis配置文件,所有需要的服務(wù)都需要在啟動文件中進行注冊,才能使用。

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連接池主要設(shè)置參數(shù),

<?php
use EasySwoole\ORM\Db\Config as DBConfig;
use EasySwoole\ORM\Db\Connection;
use EasySwoole\ORM\DbManager;
return [
    //mysql數(shù)據(jù)庫配置
    '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',    //設(shè)置獲取連接池對象超時時間
        'checkOut' => 30 * 1000,  //設(shè)置檢測連接存活執(zhí)行回收和創(chuàng)建的周期
        'maxidleTime' => 15,       //連接池對象最大閑置時間(秒)
        'maxObjectNumber' => 100,       //設(shè)置最大連接池存在連接對象數(shù)量
        'minObjectNumber' => 5,        //設(shè)置最小連接池存在連接對象數(shù)量
        'autoPing' => 5,        //設(shè)置自動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的服務(wù)屬于常駐內(nèi)存加載類型的服務(wù),所以每次修改代碼后都需要重啟服務(wù),所以為了方便,添加了熱加載目錄,熱加載原理就是當(dāng)檢測到指定目錄有代碼更新時,用傳遞信號的方式進行,指揮進程進行重新加載。

$hotReloadOptions = new \EasySwoole\HotReload\HotReloadOptions;
$hotReload = new \EasySwoole\HotReload\HotReload($hotReloadOptions);
$hotReloadOptions-&gt;setMonitorFolder([EASYSWOOLE_ROOT . '/App']);
$server = ServerManager::getInstance()-&gt;getSwooleServer();
$hotReload-&gt;attachToServer($server);

7.啟動/停止服務(wù),參數(shù)說明

-mode 說明啟動服務(wù)類型 -d 以守護進程的方式

php easyswoole server start -mode=websocket -d
php easyswoole server stop 

異步和 DB(Redis/Mysql)使用

1.高性能的異步操作

如果是不依賴于結(jié)果的計算,異步操作提高性能的有效手段之一,異步操作不需要等待結(jié)果,更好的利用CPU和I/O傳輸。

use EasySwoole\EasySwoole\Task\TaskManager;
TaskManager::getInstance()-&gt;async(function () use ($tableName,$data) {
    // todo code ...
});
  • Redis/Mysql使用

在高并發(fā)情況下,資源浪費的占用時間越短越好,可以提高程序的服務(wù)效率。在ORM默認(rèn)情況下是使用defer方法獲取pool內(nèi)的連接資源,并在協(xié)程退出時自動歸還,在此情況下,在帶來便利的同時,會造成不必要資源的浪費。

我們可以使用invoke方式,讓ORM查詢結(jié)束后馬上歸還資源,可以提高資源的利用率。

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-&gt;zAdd(self::PUSH_MSG_AUTHOR_NOTICE_SYSTEM, $uid, $fd);
    }, self::REDIS_CONN_NAME);
}
## defer方式
$redis = \EasySwoole\RedisPool\RedisPool::defer('redis');
$data = $redis-&gt;lRange(self::PUSH_MSG_COMMENT_DELAY_LISTS, 0, 1000);

WebSocket服務(wù)

1.WebSocket協(xié)議是什么

WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動發(fā)送信息給客戶端。

在沒有WebSocket協(xié)議之前,在網(wǎng)頁中,實現(xiàn)一個聊天室只能使用ajax 不斷輪詢,請求服務(wù)器是否有數(shù)據(jù)產(chǎn)生,而這樣的實現(xiàn)方法會出現(xiàn)一系列的問題:

  • 如果輪詢時間間隔太短,會導(dǎo)致客戶端和服務(wù)端在一個時間段內(nèi)不斷的進行http tcp的握手/揮手動作和http 請求頭,響應(yīng)頭的傳輸,大量消耗服務(wù)器資源,如果用戶量大的情況,會造成服務(wù)器的繁忙以至于宕機
  • 客戶端每次只能通過發(fā)送http 請求獲得服務(wù)器是否有數(shù)據(jù)返回,且數(shù)據(jù)的及時性無法保證

正因為在這種情況下,所以WebSocket出現(xiàn)了,它只需要一次http握手,就可以保持一個長連接,使得服務(wù)器可以主動發(fā)送消息給客戶端,大大減少了輪詢機制的消耗。

2.WebSocket協(xié)議實現(xiàn)原理

在實現(xiàn)websocket連線過程中,需要通過瀏覽器發(fā)出websocket連線請求,然后服務(wù)器發(fā)出回應(yīng),這個過程通常稱為握手 。

在 WebSocket API,瀏覽器和服務(wù)器只需要做一個握手的動作,然后,瀏覽器和服務(wù)器之間就形成了一條快速通道。兩者之間就直接可以數(shù)據(jù)互相傳送。在此WebSocket 協(xié)議中,為我們實現(xiàn)即時服務(wù)帶來了兩大好處:

  • Header: 互相溝通的Header是很小的-大概只有 2 Bytes
  • Server Push: 服務(wù)器的推送,服務(wù)器不再被動的接收到瀏覽器的請求之后才返回數(shù)據(jù),而是在有新數(shù)據(jù)時就主動推送給瀏覽器。
//$fd,指的是系統(tǒng)里的文件描述符fd
use EasySwoole\EasySwoole\ServerManager;
$server = ServerManager::getInstance()->getSwooleServer();
$server->push($fd,json_encode($messageData));
//獲取當(dāng)前鏈接的詳細信息
$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消息服務(wù)系統(tǒng)代碼設(shè)計詳解的詳細內(nèi)容,更多關(guān)于Swoole webSocket消息服務(wù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • PHP的Laravel框架中使用消息隊列queue及異步隊列的方法

    PHP的Laravel框架中使用消息隊列queue及異步隊列的方法

    這篇文章主要介紹了PHP的Laravel框架中使用消息隊列queue及異步隊列的方法,針對Laravel 5.0后的版本,示例環(huán)境為Linux系統(tǒng),需要的朋友可以參考下
    2016-03-03
  • PHP中is_dir()函數(shù)使用指南

    PHP中is_dir()函數(shù)使用指南

    php提供內(nèi)置函數(shù)is_dir來檢查傳入的路徑參數(shù)是否為目錄,如果是目錄則返回true。也就是說傳入的參數(shù)是文件或者不存在都為false,因此當(dāng)前參數(shù)不能說不是文件夾就是文件。另外需要注意的是參數(shù)支持相對路徑和絕對路徑。
    2015-05-05
  • PHP會員找回密碼功能的簡單實現(xiàn)

    PHP會員找回密碼功能的簡單實現(xiàn)

    下面小編就為大家?guī)硪黄狿HP會員找回密碼功能的簡單實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • function.inc.php超越php

    function.inc.php超越php

    function.inc.php超越php...
    2006-12-12
  • Laravel?Swagger?使用超詳細教程

    Laravel?Swagger?使用超詳細教程

    Swagger?是一個基于?Open?Api?規(guī)范的?API?管理工具,通過項目注解的形式自動構(gòu)建?API?文檔,擁有在線調(diào)試的功能,這篇文章主要介紹了Laravel?Swagger?使用完整教程,需要的朋友可以參考下
    2023-09-09
  • php實例分享之mysql數(shù)據(jù)備份

    php實例分享之mysql數(shù)據(jù)備份

    本代碼實現(xiàn)了表結(jié)構(gòu)和數(shù)據(jù)完全分開,默認(rèn)有一個文件會記錄所有表的結(jié)構(gòu),然后表中數(shù)據(jù)的備份 如果超過分卷的大小則會分成多個文件,不然則一個文件
    2014-05-05
  • PHP實現(xiàn)RSA加解密算法示例(生成密鑰位數(shù)為1024位的方法)

    PHP實現(xiàn)RSA加解密算法示例(生成密鑰位數(shù)為1024位的方法)

    下面小編就為大家分享一篇PHP實現(xiàn)RSA加解密算法示例(生成密鑰位數(shù)為1024位的方法),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Centos7 Yum安裝PHP7.2流程教程詳解

    Centos7 Yum安裝PHP7.2流程教程詳解

    這篇文章主要介紹了Centos7Yum安裝PHP7.2流程,本文分步驟給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-07-07
  • php獲取指定日期之間的各個周和月的起止時間

    php獲取指定日期之間的各個周和月的起止時間

    本文推薦給大家一個php類文件,可以根據(jù)指定日期獲取所在周的起始時間和結(jié)束時間,并附上使用實例,有需要的小伙伴參考下吧
    2014-11-11
  • php中使用preg_match_all匹配文章中的圖片

    php中使用preg_match_all匹配文章中的圖片

    有時候我們需要使用php獲取網(wǎng)頁中的圖片并保存下來,這里我們可以使用preg_match_all用來匹配圖片地址,需要的朋友可以參考下
    2013-02-02

最新評論