国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

workerman 如何實(shí)現(xiàn) http長輪詢

dengyd

用workerman做的http服務(wù)器,如果用作長輪詢的話如何能不造成阻塞呢?

5636 1 1
1個回答

walkor 打賞

這個是一個長輪訓(xùn)demo

use Workerman\Worker;
require_once './Workerman/Autoloader.php';

// 初始化一個worker容器,監(jiān)聽1234端口
$worker = new Worker('http://0.0.0.0:1234');
$worker->count = 1;

// 初始化一個數(shù)組,用來保存所有的長輪訓(xùn)連接
$poll_connections = array();

/*
 * 當(dāng)有客戶端發(fā)來消息時
 * 長輪訓(xùn)拉取數(shù)據(jù)url格式為 http://xxxx:1234/?type=get&uid=xxx
 * 向某uid發(fā)送數(shù)據(jù)格url格式 http://xxxx:1234/?type=send&to_uid=xxx&content=xxx
 */
$worker->onMessage = function($connection, $data)
{
    global $poll_connections;
    if(empty($_GET))
    {
        return $connection->close('type empty');
    }
    // 這個請求是長輪訓(xùn)活取數(shù)據(jù)請求
    if($_GET === 'get')
    {
        // 這里簡單的用uid驗(yàn)證用戶身份,沒傳uid視為非法請求
        if(!isset($_GET))
        {
            return $connection->close('empty uid');
        }
        // 臨時給當(dāng)前的連接對象添加一個屬性保存uid
        $connection->uid = $_GET;
        // 保存客戶端的連接對象,當(dāng)需要向這個uid推送數(shù)據(jù)時需要使用這個對象
        $poll_connections = $connection;
        // 重點(diǎn)是這里,不send任何數(shù)據(jù),則會和瀏覽器一直保持連接
        return;
    }
    // 這個請求是向某個uid長輪訓(xùn)推送數(shù)據(jù)
    elseif($_GET === 'send')
    {
        // 檢查參數(shù)是否都傳了
        if(!isset($_GET) || !isset($_GET))
        {
            return $connection->close('to_uid or content empty');
        }
        // 查找to_uid 對應(yīng)的連接對象,以便向to_uid的瀏覽器發(fā)送數(shù)據(jù)
        if(!isset($poll_connections))
        {
            // to_uid 不在線,發(fā)送不在線提示
            return $connection->close("uid:{$_GET} offline");
        }
        // 注意這里,向to_uid的瀏覽器發(fā)送了數(shù)據(jù)
        $poll_connections->close($_GET);
        // 給發(fā)送者返回成功提示
        $connection->close("send success!");
        return;
    }
    // type傳的不對,非法請求
    else
    {
        return $connection->close('unknown type :' . $_GET);
    }
};

// 當(dāng)有客戶端連接斷開時,刪除uid到連接對象的映射
$worker->onClose = function($connection)
{
    global $poll_connections;
    if(isset($connection->uid))
    {
        unset($poll_connections);
    }
};

// 運(yùn)行所有的worker(其實(shí)當(dāng)前只定義了一個)
Worker::runAll();

在線測試
長輪詢接受url
http://workerman.net:1234/?type=get&uid=123
http://workerman.net:1234/?type=get&uid=456
http://workerman.net:1234/?type=get&uid=789
...

發(fā)送消息url
http://workerman.net:1234/?type=send&to_uid=123&content=hello
http://workerman.net:1234/?type=send&to_uid=456&content=hello
...

技巧是不向?yàn)g覽器send數(shù)據(jù),瀏覽器就會一直等待數(shù)據(jù),然后服務(wù)端業(yè)務(wù)該干嘛干嘛,服務(wù)端不會阻塞,等需要發(fā)送數(shù)據(jù)時,在向?yàn)g覽器send。

這樣一個worker進(jìn)程就能維持大量的連接(上萬或者數(shù)十萬),服務(wù)端是非阻塞的,性能很高,服務(wù)器也不會有任何負(fù)載

  • 暫無評論
年代過于久遠(yuǎn),無法發(fā)表回答
??